Merge remote-tracking branch 'origin/develop'

# Conflicts:
#	Dockerfile
#	resources/views/auth/login.blade.php
This commit is contained in:
snipe 2016-11-15 17:46:05 -08:00
commit 91caba05b7
152 changed files with 2949 additions and 571 deletions

View file

@ -13,7 +13,7 @@
#### Please confirm you have done the following before posting your bug report:
- [ ] I have enabled debug mode
- [ ] I have read [checked the Common Issues page](http://docs.snipeitapp.com/common-issues.html)
- [ ] I have read [checked the Common Issues page](https://snipe-it.readme.io/docs/common-issues)
-----
#### Please provide answers to these questions before posting your bug report:
@ -21,7 +21,7 @@
- Version of Snipe-IT you're running
- What OS and web server you're running Snipe-IT on
- What method you used to install Snipe-IT (install.sh, manual installation, docker, etc)
- If you're getting an error in your browser, include that error
- WITH DEBUG TURNED ON, if you're getting an error in your browser, include that error
- What specific Snipe-IT page you're on, and what specific element you're interacting with to trigger the error
- If a stacktrace is provided in the error, include that too.
- Any errors that appear in your browser's error console.

View file

@ -54,10 +54,10 @@ COPY docker/docker.env /var/www/html/.env
RUN chown -R docker /var/www/html
RUN \
rm -r "/var/www/html/storage/private_uploads" && ln -fs "/var/lib/snipeit/data/private_uploads" "/var/www/html/storage/private_uploads" \
&& mkdir -p "/var/lib/snipeit/data/uploads/{assets,avatars,barcodes,models,suppliers}" \
&& rm -rf "/var/www/html/public/uploads" && ln -fs "/var/lib/snipeit/data/uploads" "/var/www/html/public/uploads" \
&& rm -r "/var/www/html/storage/app/backups" && ln -fs "/var/lib/snipeit/dumps" "/var/www/html/storage/app/backups"
rm -r "/var/www/html/storage/private_uploads" && ln -fs "/var/lib/snipeit/data/private_uploads" "/var/www/html/storage/private_uploads" \
&& mkdir -p "/var/lib/snipeit/data/uploads/{assets,avatars,barcodes,models,suppliers}" \
&& rm -rf "/var/www/html/public/uploads" && ln -fs "/var/lib/snipeit/data/uploads" "/var/www/html/public/uploads" \
&& rm -r "/var/www/html/storage/app/backups" && ln -fs "/var/lib/snipeit/dumps" "/var/www/html/storage/app/backups"
############## DEPENDENCIES via COMPOSER ###################

View file

@ -0,0 +1,164 @@
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use App\Models\Setting;
use App\Models\Ldap;
use App\Models\User;
use App\Models\Location;
use Log;
class LdapSync extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'snipeit:ldap-sync {--location=} {--location_id=} {--summary}';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Command line LDAP sync';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
ini_set('max_execution_time', 600); //600 seconds = 10 minutes
ini_set('memory_limit', '500M');
$ldap_result_username = Setting::getSettings()->ldap_username_field;
$ldap_result_last_name = Setting::getSettings()->ldap_lname_field;
$ldap_result_first_name = Setting::getSettings()->ldap_fname_field;
$ldap_result_active_flag = Setting::getSettings()->ldap_active_flag_field;
$ldap_result_emp_num = Setting::getSettings()->ldap_emp_num;
$ldap_result_email = Setting::getSettings()->ldap_email;
try {
$ldapconn = Ldap::connectToLdap();
} catch (\Exception $e) {
LOG::error($e);
}
try {
Ldap::bindAdminToLdap($ldapconn);
} catch (\Exception $e) {
LOG::error($e);
}
$summary = array();
$results = Ldap::findLdapUsers();
if ($this->option('location')!='') {
$location = Location::where('name','=',$this->option('location'))->first();
LOG::debug('Location name '.$this->option('location').' passed');
LOG::debug('Importing to '.$location->name.' ('.$location->id.')');
} elseif ($this->option('location_id')!='') {
$location = Location::where('id','=',$this->option('location_id'))->first();
LOG::debug('Location ID '.$this->option('location_id').' passed');
LOG::debug('Importing to '.$location->name.' ('.$location->id.')');
} else {
$location = new Location;
}
if (!isset($location)) {
LOG::debug('That location is invalid, so no location will be assigned.');
}
$tmp_pass = substr(str_shuffle("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), 0, 20);
$pass = bcrypt($tmp_pass);
for ($i = 0; $i < $results["count"]; $i++) {
if (empty($ldap_result_active_flag) || $results[$i][$ldap_result_active_flag][0] == "TRUE") {
$item = array();
$item["username"] = isset($results[$i][$ldap_result_username][0]) ? $results[$i][$ldap_result_username][0] : "";
$item["employee_number"] = isset($results[$i][$ldap_result_emp_num][0]) ? $results[$i][$ldap_result_emp_num][0] : "";
$item["lastname"] = isset($results[$i][$ldap_result_last_name][0]) ? $results[$i][$ldap_result_last_name][0] : "";
$item["firstname"] = isset($results[$i][$ldap_result_first_name][0]) ? $results[$i][$ldap_result_first_name][0] : "";
$item["email"] = isset($results[$i][$ldap_result_email][0]) ? $results[$i][$ldap_result_email][0] : "" ;
// User exists
$item["createorupdate"] = 'updated';
if (!$user = User::where('username', $item["username"])->first()) {
$user = new User;
$user->password = $pass;
$item["createorupdate"] = 'created';
}
// Create the user if they don't exist.
$user->first_name = e($item["firstname"]);
$user->last_name = e($item["lastname"]);
$user->username = e($item["username"]);
$user->email = e($item["email"]);
$user->employee_num = e($item["employee_number"]);
$user->activated = 1;
if ($location) {
$user->location_id = e($location->id);
}
$user->notes = 'Imported from LDAP';
$user->ldap_import = 1;
$errors = '';
if ($user->save()) {
$item["note"] = $item["createorupdate"];
$item["status"]='success';
} else {
foreach ($user->getErrors()->getMessages() as $key => $err) {
$errors .= $err[0];
}
$item["note"] = $errors;
$item["status"]='error';
}
array_push($summary, $item);
}
}
if ($this->option('summary')) {
for ($x = 0; $x < count($summary); $x++) {
if ($summary[$x]['status']=='error') {
$this->error('ERROR: '.$summary[$x]['firstname'].' '.$summary[$x]['lastname'].' (username: '.$summary[$x]['username'].' was not imported: '.$summary[$x]['note'] );
} else {
$this->info('User '.$summary[$x]['firstname'].' '.$summary[$x]['lastname'].' (username: '.$summary[$x]['username'].' was '.strtoupper($summary[$x]['createorupdate']).'.');
}
}
} else {
return $summary;
}
}
}

View file

@ -23,6 +23,7 @@ class Kernel extends ConsoleKernel
Commands\SystemBackup::class,
Commands\DisableLDAP::class,
Commands\Purge::class,
Commands\LdapSync::class,
];
/**

View file

@ -530,9 +530,11 @@ class AccessoriesController extends Controller
**/
public function getDatatable(Request $request)
{
$accessories = Company::scopeCompanyables(Accessory::select('accessories.*')->with('category', 'company'))
->whereNull('accessories.deleted_at');
$accessories = Company::scopeCompanyables(
Accessory::select('accessories.*')
->whereNull('accessories.deleted_at')
->with('category', 'company', 'manufacturer', 'users', 'location')
);
if (Input::has('search')) {
$accessories = $accessories->TextSearch(e(Input::get('search')));
}

View file

@ -0,0 +1,18 @@
<?php
namespace App\Http\Controllers;
use App\Helpers\Helper;
use Response;
class ActionlogController extends Controller
{
public function displaySig($filename)
{
$file = config('app.private_uploads') . '/signatures/' . $filename;
$filetype = Helper::checkUploadIsImage($file);
$contents = file_get_contents($file);
return Response::make($contents)->header('Content-Type', $filetype);
}
}

View file

@ -416,7 +416,7 @@ class AssetModelsController extends Controller
public function getDatatable($status = null)
{
$models = AssetModel::with('category', 'assets', 'depreciation');
$models = AssetModel::with('category', 'assets', 'depreciation', 'manufacturer');
switch ($status) {
case 'Deleted':
@ -491,7 +491,7 @@ class AssetModelsController extends Controller
*/
public function getDataView($modelID)
{
$assets = Asset::where('model_id', '=', $modelID)->with('company');
$assets = Asset::where('model_id', '=', $modelID)->with('company', 'assetstatus');
if (Input::has('search')) {
$assets = $assets->TextSearch(e(Input::get('search')));

View file

@ -15,6 +15,7 @@ use Input;
use Redirect;
use Log;
use View;
use PragmaRX\Google2FA\Google2FA;
@ -48,7 +49,7 @@ class AuthController extends Controller
*/
public function __construct()
{
$this->middleware('guest', ['except' => 'logout']);
$this->middleware('guest', ['except' => ['logout','postTwoFactorAuth','getTwoFactorAuth','getTwoFactorEnroll']]);
}
@ -63,6 +64,51 @@ class AuthController extends Controller
return View::make('auth.login');
}
private function login_via_ldap(Request $request)
{
LOG::debug("Binding user to LDAP.");
$ldap_user = Ldap::findAndBindUserLdap($request->input('username'), $request->input('password'));
if(!$ldap_user) {
LOG::debug("LDAP user ".$request->input('username')." not found in LDAP or could not bind");
throw new \Exception("Could not find user in LDAP directory");
} else {
LOG::debug("LDAP user ".$request->input('username')." successfully bound to LDAP");
}
// Check if the user exists in the database
$user = User::where('username', '=', Input::get('username'))->whereNull('deleted_at')->first();
LOG::debug("Local auth lookup complete");
// The user does not exist in the database. Try to get them from LDAP.
// If user does not exist and authenticates successfully with LDAP we
// will create it on the fly and sign in with default permissions
if (!$user) {
LOG::debug("Local user ".Input::get('username')." does not exist");
LOG::debug("Creating local user ".Input::get('username'));
if ($user = Ldap::createUserFromLdap($ldap_user)) { //this handles passwords on its own
LOG::debug("Local user created.");
} else {
LOG::debug("Could not create local user.");
throw new \Exception("Could not create local user");
}
// If the user exists and they were imported from LDAP already
} else {
LOG::debug("Local user ".$request->input('username')." exists in database. Updating existing user against LDAP.");
$ldap_attr = Ldap::parseAndMapLdapAttributes($ldap_user);
if (Setting::getSettings()->ldap_pw_sync=='1') {
$user->password = bcrypt($request->input('password'));
}
$user->email = $ldap_attr['email'];
$user->first_name = $ldap_attr['firstname'];
$user->last_name = $ldap_attr['lastname'];
$user->save();
} // End if(!user)
return $user;
}
/**
@ -77,120 +123,123 @@ class AuthController extends Controller
if ($validator->fails()) {
return redirect()->back()->withInput()->withErrors($validator);
}
$user = null;
// Should we even check for LDAP users?
if (Setting::getSettings()->ldap_enabled=='1') {
LOG::debug("LDAP is enabled.");
// Check if the user exists in the database
$user = User::where('username', '=', Input::get('username'))->whereNull('deleted_at')->first();
LOG::debug("Local auth lookup complete");
try {
Ldap::findAndBindUserLdap($request->input('username'), $request->input('password'));
LOG::debug("Binding user to LDAP.");
$user = $this->login_via_ldap($request);
Auth::login($user, true);
} catch (\Exception $e) {
LOG::debug("User ".Input::get('username').' did not authenticate successfully against LDAP.');
//$ldap_error = $e->getMessage();
// return redirect()->back()->withInput()->with('error',$e->getMessage());
if(Setting::getSettings()->ldap_pw_sync!='1') {
return redirect()->back()->withInput()->with('error',$e->getMessage());
}
}
// The user does not exist in the database. Try to get them from LDAP.
// If user does not exist and authenticates sucessfully with LDAP we
// will create it on the fly and sign in with default permissions
if (!$user) {
LOG::debug("Local user ".Input::get('username')." does not exist");
try {
if ($userattr = Ldap::findAndBindUserLdap($request->input('username'), $request->input('password'))) {
LOG::debug("Creating local user ".Input::get('username'));
if ($newuser = Ldap::createUserFromLdap($userattr)) {
LOG::debug("Local user created.");
} else {
LOG::debug("Could not create local user.");
}
} else {
LOG::debug("User did not authenticate correctly against LDAP. No local user was created.");
}
} catch (\Exception $e) {
return redirect()->back()->withInput()->with('error',$e->getMessage());
}
// If the user exists and they were imported from LDAP already
} else {
LOG::debug("Local user ".Input::get('username')." exists in database. Authenticating existing user against LDAP.");
if ($ldap_user = Ldap::findAndBindUserLdap($request->input('username'), $request->input('password'))) {
$ldap_attr = Ldap::parseAndMapLdapAttributes($ldap_user);
LOG::debug("Valid LDAP login. Updating the local data.");
if (Setting::getSettings()->ldap_pw_sync=='1') {
$user->password = bcrypt($request->input('password'));
}
$user->email = $ldap_attr['email'];
$user->first_name = $ldap_attr['firstname'];
$user->last_name = $ldap_attr['lastname'];
$user->save();
if (Setting::getSettings()->ldap_pw_sync!='1') {
Auth::login($user, true);
// Redirect to the users page
return redirect()->to('/home')->with('success', trans('auth/message.signin.success'));
}
} else {
LOG::debug("User ".Input::get('username')." did not authenticate correctly against LDAP. Local user was not updated.");
}// End LDAP auth
} // End if(!user)
// NO LDAP enabled - just try to login the user normally
}
LOG::debug("Authenticating user against database.");
// Try to log the user in
if (!Auth::attempt(Input::only('username', 'password'), Input::get('remember-me', 0))) {
LOG::debug("Local authentication failed.");
// throw new Cartalyst\Sentry\Users\UserNotFoundException();
return redirect()->back()->withInput()->with('error', trans('auth/message.account_not_found'));
// If the user wasn't authenticated via LDAP, skip to local auth
if(!$user) {
LOG::debug("Authenticating user against database.");
// Try to log the user in
if (!Auth::attempt(Input::only('username', 'password'), Input::get('remember-me', 0))) {
LOG::debug("Local authentication failed.");
return redirect()->back()->withInput()->with('error', trans('auth/message.account_not_found'));
}
}
// Get the page we were before
$redirect = \Session::get('loginRedirect', 'home');
// Unset the page we were before from the session
\Session::forget('loginRedirect');
// Redirect to the users page
return redirect()->to($redirect)->with('success', trans('auth/message.signin.success'));
// Ooops.. something went wrong
return redirect()->back()->withInput()->withErrors($this->messageBag);
}
/**
* Two factor enrollment page
*
* @return Redirect
*/
public function getTwoFactorEnroll()
{
if (!Auth::check()) {
return redirect()->route('login')->with('error', 'You must be logged in.');
}
$user = Auth::user();
$google2fa = app()->make('PragmaRX\Google2FA\Contracts\Google2FA');
if ($user->two_factor_secret=='') {
$user->two_factor_secret = $google2fa->generateSecretKey(32);
$user->save();
}
$google2fa_url = $google2fa->getQRCodeGoogleUrl(
urlencode(Setting::getSettings()->site_name),
urlencode($user->username),
$user->two_factor_secret
);
return View::make('auth.two_factor_enroll')->with('google2fa_url',$google2fa_url);
}
/**
* Two factor code form page
*
* @return Redirect
*/
public function getTwoFactorAuth() {
return View::make('auth.two_factor');
}
/**
* Two factor code submission
*
* @return Redirect
*/
public function postTwoFactorAuth(Request $request) {
if (!Auth::check()) {
return redirect()->route('login')->with('error', 'You must be logged in.');
}
$user = Auth::user();
$secret = $request->get('two_factor_secret');
$google2fa = app()->make('PragmaRX\Google2FA\Contracts\Google2FA');
$valid = $google2fa->verifyKey($user->two_factor_secret, $secret);
if ($valid) {
$user->two_factor_enrolled = 1;
$user->save();
$request->session()->put('2fa_authed', 'true');
return redirect()->route('home')->with('success', 'You are logged in!');
}
return redirect()->route('two-factor')->with('error', 'Invalid two-factor code');
}
/**
* Logout page.
*
* @return Redirect
*/
public function logout()
public function logout(Request $request)
{
// Log the user out
$request->session()->forget('2fa_authed');
Auth::logout();
// Redirect to the users page
return redirect()->route('home')->with('success', 'You have successfully logged out!');
return redirect()->route('login')->with('success', 'You have successfully logged out!');
}

View file

@ -307,9 +307,9 @@ class CategoriesController extends Controller
public function getDataViewAssets($categoryID)
{
$category = Category::with('assets.company')->find($categoryID);
$category = Category::find($categoryID);
$category = $category->load('assets.company', 'assets.model', 'assets.assetstatus', 'assets.assigneduser');
$category_assets = $category->assets();
if (Input::has('search')) {
$category_assets = $category_assets->TextSearch(e(Input::get('search')));
}
@ -333,7 +333,6 @@ class CategoriesController extends Controller
$count = $category_assets->count();
$category_assets = $category_assets->skip($offset)->take($limit)->get();
$rows = array();
foreach ($category_assets as $asset) {
$actions = '';
@ -364,7 +363,7 @@ class CategoriesController extends Controller
'assigned_to' => ($asset->assigneduser) ? (string)link_to('/admin/users/'.$asset->assigneduser->id.'/view', $asset->assigneduser->fullName()): '',
'change' => $inout,
'actions' => $actions,
'companyName' => Company::getName($asset),
'companyName' => is_null($asset->company) ? '' : e($asset->company->name)
);
}

View file

@ -390,8 +390,11 @@ class ConsumablesController extends Controller
*/
public function getDatatable()
{
$consumables = Company::scopeCompanyables(Consumable::select('consumables.*')->whereNull('consumables.deleted_at')
->with('company', 'location', 'category', 'users'));
$consumables = Company::scopeCompanyables(
Consumable::select('consumables.*')
->whereNull('consumables.deleted_at')
->with('company', 'location', 'category', 'users', 'manufacturer')
);
if (Input::has('search')) {
$consumables = $consumables->TextSearch(e(Input::get('search')));

View file

@ -11,6 +11,7 @@ use App\Models\AssetModel;
use Lang;
use Auth;
use Illuminate\Http\Request;
use Log;
/**
* This controller handles all actions related to Custom Asset Fields for
@ -210,21 +211,15 @@ class CustomFieldsController extends Controller
*/
public function show($id)
{
//$id=$parameters[0];
$cfset=CustomFieldset::find($id);
$cfset = CustomFieldset::with('fields')->where('id','=',$id)->orderBy('id','ASC')->first();
$custom_fields_list = ["" => "Add New Field to Fieldset"] + CustomField::lists("name", "id")->toArray();
//print_r($parameters);
//
$custom_fields_list=["" => "Add New Field to Fieldset"] + CustomField::lists("name", "id")->toArray();
// print_r($custom_fields_list);
$maxid=0;
foreach ($cfset->fields as $field) {
// print "Looking for: ".$field->id;
$maxid = 0;
foreach ($cfset->fields() as $field) {
if ($field->pivot->order > $maxid) {
$maxid=$field->pivot->order;
}
if (isset($custom_fields_list[$field->id])) {
// print "Found ".$field->id.", so removing it.<br>";
unset($custom_fields_list[$field->id]);
}
}
@ -274,14 +269,14 @@ class CustomFieldsController extends Controller
public function destroy($id)
{
//
$fieldset=CustomFieldset::find($id);
$fieldset = CustomFieldset::find($id);
$models = AssetModel::where("fieldset_id", "=", $id);
if ($models->count()==0) {
if ($models->count() == 0) {
$fieldset->delete();
return redirect()->route("admin.custom_fields.index")->with("success", trans('admin/custom_fields/message.fieldset.delete.success'));
} else {
return redirect()->route("admin.custom_fields.index")->with("error", trans('admin/custom_fields/message.fieldset.delete.in_use')); //->with("models",$models);
return redirect()->route("admin.custom_fields.index")->with("error", trans('admin/custom_fields/message.fieldset.delete.in_use'));
}
}
@ -294,18 +289,23 @@ class CustomFieldsController extends Controller
* @since [v3.0]
* @return Array
*/
public function postReorder($id)
public function postReorder(Request $request, $id)
{
$fieldset=CustomFieldset::find($id);
$fieldset = CustomFieldset::find($id);
$fields = array();
$order_array = array();
$items = Input::get('item');
foreach ($fieldset->fields as $field) {
$value = array_shift($items);
$fields[$field->id] = ['required' => $field->pivot->required, 'order' => $value];
$items = $request->input('item');
foreach ($items as $order => $field_id) {
$order_array[$field_id] = $order;
}
return $fieldset->fields()->sync($fields);
foreach ($fieldset->fields as $field) {
$fields[$field->id] = ['required' => $field->pivot->required, 'order' => $order_array[$field->id]];
}
return $fieldset->fields()->sync($fields);
}
}

View file

@ -79,7 +79,7 @@ class DashboardController extends Controller
return View::make('dashboard')->with('asset_stats', $asset_stats);
} else {
// Redirect to the profile page
return redirect()->route('view-assets');
return redirect()->intended('account/view-assets');
}
}
}

View file

@ -742,6 +742,7 @@ class LicensesController extends Controller
{
$license = License::find($licenseId);
$license = $license->load('assignedusers', 'licenseSeats.user', 'licenseSeats.asset');
if (isset($license->id)) {
@ -947,17 +948,28 @@ class LicensesController extends Controller
*/
public function getDatatable()
{
$licenses = Company::scopeCompanyables(License::with('company'));
$licenses = Company::scopeCompanyables(License::with('company', 'licenseSeatsRelation', 'manufacturer'));
if (Input::has('search')) {
$licenses = $licenses->TextSearch(Input::get('search'));
}
$allowed_columns = ['id','name','purchase_cost','expiration_date','purchase_order','order_number','notes','purchase_date','serial'];
$allowed_columns = ['id','name','purchase_cost','expiration_date','purchase_order','order_number','notes','purchase_date','serial','manufacturer','company'];
$order = Input::get('order') === 'asc' ? 'asc' : 'desc';
$sort = in_array(Input::get('sort'), $allowed_columns) ? e(Input::get('sort')) : 'created_at';
$licenses = $licenses->orderBy($sort, $order);
switch ($sort) {
case 'manufacturer':
$licenses = $licenses->OrderManufacturer($order);
break;
case 'company':
$licenses = $licenses->OrderCompany($order);
break;
default:
$licenses = $licenses->orderBy($sort, $order);
break;
}
$licenseCount = $licenses->count();
$licenses = $licenses->skip(Input::get('offset'))->take(Input::get('limit'))->get();
@ -991,7 +1003,7 @@ class LicensesController extends Controller
'id' => $license->id,
'name' => (string) link_to('/admin/licenses/'.$license->id.'/view', $license->name),
'serial' => (string) link_to('/admin/licenses/'.$license->id.'/view', mb_strimwidth($license->serial, 0, 50, "...")),
'totalSeats' => $license->totalSeatsByLicenseID(),
'totalSeats' => $license->licenseSeatsCount,
'remaining' => $license->remaincount(),
'license_name' => e($license->license_name),
'license_email' => e($license->license_email),
@ -1002,7 +1014,7 @@ class LicensesController extends Controller
'order_number' => ($license->order_number) ? e($license->order_number) : '',
'notes' => ($license->notes) ? e($license->notes) : '',
'actions' => $actions,
'companyName' => is_null($license->company) ? '' : e($license->company->name),
'company' => is_null($license->company) ? '' : e($license->company->name),
'manufacturer' => $license->manufacturer ? (string) link_to('/admin/settings/manufacturers/'.$license->manufacturer_id.'/view', $license->manufacturer->name) : ''
);
}

View file

@ -257,7 +257,7 @@ class ManufacturersController extends Controller
*/
public function getDataView($manufacturerId, $itemtype = null)
{
$manufacturer = Manufacturer::with('assets.company')->find($manufacturerId);
$manufacturer = Manufacturer::find($manufacturerId);
switch ($itemtype) {
case "assets":
@ -276,6 +276,7 @@ class ManufacturersController extends Controller
protected function getDataAssetsView(Manufacturer $manufacturer)
{
$manufacturer = $manufacturer->load('assets.model', 'assets.assigneduser', 'assets.assetstatus', 'assets.company');
$manufacturer_assets = $manufacturer->assets;
if (Input::has('search')) {
@ -329,20 +330,22 @@ class ManufacturersController extends Controller
'serial' => e($asset->serial),
'assigned_to' => ($asset->assigneduser) ? (string)link_to('/admin/users/'.$asset->assigneduser->id.'/view', e($asset->assigneduser->fullName())): '',
'actions' => $actions,
'companyName' => e(Company::getName($asset)),
// 'companyName' => e(Company::getName($asset)),
'companyName' => is_null($asset->company) ? '' : $asset->company->name
);
if (isset($inout)) {
$row['change'] = $inout;
}
if (isset($inout)) {
$row['change'] = $inout;
}
}
$data = array('total' => $count, 'rows' => $rows);
return $data;
}
protected function getDataLicensesView(Manufacturer $manufacturer)
{
$manufacturer = $manufacturer->load('licenses.company', 'licenses.manufacturer', 'licenses.licenseSeatsRelation');
$licenses = $manufacturer->licenses;
if (Input::has('search')) {
@ -380,7 +383,7 @@ class ManufacturersController extends Controller
'id' => $license->id,
'name' => (string) link_to('/admin/licenses/'.$license->id.'/view', $license->name),
'serial' => (string) link_to('/admin/licenses/'.$license->id.'/view', mb_strimwidth($license->serial, 0, 50, "...")),
'totalSeats' => $license->totalSeatsByLicenseID(),
'totalSeats' => $license->licenseSeatCount,
'remaining' => $license->remaincount(),
'license_name' => e($license->license_name),
'license_email' => e($license->license_email),
@ -403,6 +406,13 @@ class ManufacturersController extends Controller
public function getDataAccessoriesView(Manufacturer $manufacturer)
{
$manufacturer = $manufacturer->load(
'accessories.location',
'accessories.company',
'accessories.category',
'accessories.manufacturer',
'accessories.users'
);
$accessories = $manufacturer->accessories;
if (Input::has('search')) {
@ -461,6 +471,13 @@ class ManufacturersController extends Controller
public function getDataConsumablesView($manufacturer)
{
$manufacturer = $manufacturer->load(
'consumables.location',
'consumables.company',
'consumables.category',
'consumables.manufacturer',
'consumables.users'
);
$consumables = $manufacturer->consumables;
if (Input::has('search')) {

View file

@ -8,6 +8,8 @@ use App\Models\Location;
use View;
use Auth;
use App\Helpers\Helper;
use App\Models\Setting;
use Gate;
/**
* This controller handles all actions related to User Profiles for
@ -53,6 +55,11 @@ class ProfileController extends Controller
$user->gravatar = e(Input::get('gravatar'));
$user->locale = e(Input::get('locale'));
if ((Gate::allows('self.two_factor')) && ((Setting::getSettings()->two_factor_enabled=='1') && (!config('app.lock_passwords')))) {
$user->two_factor_optin = e(Input::get('two_factor_optin', '0'));
}
if (Input::file('avatar')) {
$image = Input::file('avatar');
$file_name = str_slug($user->first_name."-".$user->last_name).".".$image->getClientOriginalExtension();

View file

@ -311,7 +311,7 @@ class ReportsController extends Controller
$activitylogs = Company::scopeCompanyables(Actionlog::with('item', 'user', 'target'))->orderBy('created_at', 'DESC');
if (Input::has('search')) {
$activity = $activity->TextSearch(e(Input::get('search')));
$activitylogs = $activitylogs->TextSearch(e(Input::get('search')));
}
if (Input::has('offset')) {
@ -356,8 +356,10 @@ class ReportsController extends Controller
$activity_item = '<a href="'.route('view/hardware', $activity->item_id).'">'.e($activity->item->asset_tag).' - '. e($activity->item->showAssetName()).'</a>';
$item_type = 'asset';
} elseif ($activity->item) {
$activity_item = '<a href="'.route('view/'. $activity->itemType(), $activity->item_id).'">'.e($activity->item->name).'</a>';
$activity_item = '<a href="' . route('view/' . $activity->itemType(),
$activity->item_id) . '">' . e($activity->item->name) . '</a>';
$item_type = $activity->itemType();
} else {
$activity_item = "unkonwn";
$item_type = "null";
@ -378,6 +380,9 @@ class ReportsController extends Controller
} else {
$activity_target = '';
}
} elseif (($activity->action_type=='accepted') || ($activity->action_type=='declined')) {
$activity_target = '<a href="' . route('view/user', $activity->item->assigneduser->id) . '">' . e($activity->item->assigneduser->fullName()) . '</a>';
} elseif ($activity->action_type=='requested') {
if ($activity->user) {
$activity_target = '<a href="'.route('view/user', $activity->user_id).'">'.$activity->user->fullName().'</a>';
@ -568,6 +573,10 @@ class ReportsController extends Controller
$header[] = 'Value';
$header[] = 'Diff';
}
if (e(Input::get('expected_checkin')) == '1') {
$header[] = trans('admin/hardware/form.expected_checkin');
}
foreach ($customfields as $customfield) {
if (e(Input::get($customfield->db_column_name())) == '1') {
@ -696,6 +705,13 @@ class ReportsController extends Controller
$row[] = '"' . Helper::formatCurrencyOutput($depreciation) . '"';
$row[] = '"' . Helper::formatCurrencyOutput($asset->purchase_cost) . '"';
}
if (e(Input::get('expected_checkin')) == '1') {
if ($asset->expected_checkin) {
$row[] = '"' .e($asset->expected_checkin). '"';
} else {
$row[] = ''; // Empty string if blankd
}
}
foreach ($customfields as $customfield) {
$column_name = $customfield->db_column_name();

View file

@ -260,10 +260,7 @@ class SettingsController extends Controller
*/
public function getIndex()
{
// Grab all the settings
$settings = Setting::all();
// Show the page
return View::make('settings/index', compact('settings'));
}
@ -316,10 +313,17 @@ class SettingsController extends Controller
}
if (config('app.lock_passwords')==false) {
if (!config('app.lock_passwords')) {
$setting->site_name = e(Input::get('site_name'));
$setting->brand = e(Input::get('brand'));
$setting->custom_css = e(Input::get('custom_css'));
if (Input::get('two_factor_enabled')=='') {
$setting->two_factor_enabled = null;
} else {
$setting->two_factor_enabled = e(Input::get('two_factor_enabled'));
}
}
if (Input::get('per_page')!='') {
@ -345,6 +349,7 @@ class SettingsController extends Controller
$setting->email_domain = e(Input::get('email_domain'));
$setting->email_format = e(Input::get('email_format'));
$setting->username_format = e(Input::get('username_format'));
$setting->require_accept_signature = e(Input::get('require_accept_signature'));
$setting->labels_per_page = e(Input::get('labels_per_page'));
@ -360,6 +365,7 @@ class SettingsController extends Controller
$setting->labels_pagewidth = e(Input::get('labels_pagewidth'));
$setting->labels_pageheight = e(Input::get('labels_pageheight'));
if (Input::has('labels_display_name')) {
$setting->labels_display_name = 1;
} else {
@ -379,7 +385,7 @@ class SettingsController extends Controller
}
$alert_email = rtrim(Input::get('alert_email'), ',');
$alert_email = trim(Input::get('alert_email'));
$alert_email = trim($alert_email);
$setting->alert_email = e($alert_email);
$setting->alerts_enabled = e(Input::get('alerts_enabled', '0'));
@ -410,10 +416,8 @@ class SettingsController extends Controller
$setting->ldap_tls = e(Input::get('ldap_tls', '0'));
$setting->ldap_pw_sync = e(Input::get('ldap_pw_sync', '0'));
// If validation fails, we'll exit the operation now.
if ($setting->save()) {
return redirect()->to("admin/settings/app")->with('success', trans('admin/settings/message.update.success'));
} else {
return redirect()->back()->withInput()->withErrors($setting->getErrors());
}

View file

@ -242,7 +242,7 @@ class SuppliersController extends Controller
public function getDatatable()
{
$suppliers = Supplier::select(array('id','name','address','address2','city','state','country','fax', 'phone','email','contact'))
$suppliers = Supplier::with('assets', 'licenses')->select(array('id','name','address','address2','city','state','country','fax', 'phone','email','contact'))
->whereNull('deleted_at');
if (Input::has('search')) {
@ -283,8 +283,8 @@ class SuppliersController extends Controller
'phone' => e($supplier->phone),
'fax' => e($supplier->fax),
'email' => ($supplier->email!='') ? '<a href="mailto:'.e($supplier->email).'">'.e($supplier->email).'</a>' : '',
'assets' => $supplier->num_assets(),
'licenses' => $supplier->num_licenses(),
'assets' => $supplier->assets->count(),
'licenses' => $supplier->licenses->count(),
'actions' => $actions
);
}

View file

@ -125,7 +125,16 @@ class UsersController extends Controller
$user->company_id = e(Company::getIdForUser($request->input('company_id')));
$user->manager_id = e($request->input('manager_id'));
$user->notes = e($request->input('notes'));
$user->permissions = json_encode($request->input('permission'));
// Strip out the superuser permission if the user isn't a superadmin
$permissions_array = $request->input('permission');
if (!Auth::user()->isSuperUser()) {
unset($permissions_array['superuser']);
}
$user->permissions = json_encode($permissions_array);
if ($user->manager_id == "") {
@ -301,26 +310,42 @@ class UsersController extends Controller
}
try {
// Get the user information
$user = User::find($id);
// Figure out of this user was an admin before this edit
$orig_permissions_array = $user->decodePermissions();
if (is_array($orig_permissions_array)) {
if (array_key_exists('superuser', $orig_permissions_array)) {
$orig_superuser = $orig_permissions_array['superuser'];
} else {
$orig_superuser = '0';
}
} else {
$orig_superuser = '0';
}
if (!Company::isCurrentUserHasAccess($user)) {
return redirect()->route('users')->with('error', trans('general.insufficient_permissions'));
}
} catch (UserNotFoundException $e) {
// Prepare the error message
$error = trans('admin/users/message.user_not_found', compact('id'));
// Redirect to the user management page
return redirect()->route('users')->with('error', $error);
}
// First handle anything exclusive to editing.
if ($request->has('groups')) {
$user->groups()->sync($request->input('groups'));
} else {
$user->groups()->sync(array());
// Only save groups if the user is a super user
if (Auth::user()->isSuperUser()) {
if ($request->has('groups')) {
$user->groups()->sync($request->input('groups'));
} else {
$user->groups()->sync(array());
}
}
// Do we want to update the user password?
if ($request->has('password')) {
$user->password = bcrypt($request->input('password'));
@ -334,6 +359,7 @@ class UsersController extends Controller
// Update the user
$user->first_name = e($request->input('first_name'));
$user->last_name = e($request->input('last_name'));
$user->two_factor_optin = e($request->input('two_factor_optin'));
$user->locale = e($request->input('locale'));
$user->employee_num = e($request->input('employee_num'));
$user->activated = e($request->input('activated', $user->activated));
@ -343,7 +369,17 @@ class UsersController extends Controller
$user->company_id = e(Company::getIdForUser($request->input('company_id')));
$user->manager_id = e($request->input('manager_id'));
$user->notes = e($request->input('notes'));
$user->permissions = json_encode($request->input('permission'));
// Strip out the superuser permission if the user isn't a superadmin
$permissions_array = $request->input('permission');
if (!Auth::user()->isSuperUser()) {
unset($permissions_array['superuser']);
$permissions_array['superuser'] = $orig_superuser;
}
$user->permissions = json_encode($permissions_array);
if ($user->manager_id == "") {
$user->manager_id = null;
@ -892,7 +928,7 @@ class UsersController extends Controller
$sort = e(Input::get('sort'));
}
$users = User::select(array('users.id','users.employee_num','users.jobtitle','users.email','users.username','users.location_id','users.manager_id','users.first_name','users.last_name','users.created_at','users.notes','users.company_id', 'users.deleted_at','users.activated'))
$users = User::select(array('users.id','users.employee_num','users.two_factor_enrolled','users.jobtitle','users.email','users.username','users.location_id','users.manager_id','users.first_name','users.last_name','users.created_at','users.notes','users.company_id', 'users.deleted_at','users.activated'))
->with('assets', 'accessories', 'consumables', 'licenses', 'manager', 'groups', 'userloc', 'company','throttle');
$users = Company::scopeCompanyables($users);
@ -919,7 +955,8 @@ class UsersController extends Controller
$allowed_columns =
[
'last_name','first_name','email','jobtitle','username','employee_num',
'assets','accessories', 'consumables','licenses','groups','activated','created_at'
'assets','accessories', 'consumables','licenses','groups','activated','created_at',
'two_factor_enrolled','two_factor_optin'
];
$sort = in_array($sort, $allowed_columns) ? $sort : 'first_name';
@ -969,7 +1006,7 @@ class UsersController extends Controller
$actions .= ' <span class="btn delete-asset btn-danger btn-sm disabled"><i class="fa fa-trash icon-white"></i></span>';
}
} else {
$actions.='foo';
$actions.='';
}
}
@ -978,7 +1015,7 @@ class UsersController extends Controller
$rows[] = array(
'id' => $user->id,
'checkbox' => ($status!='deleted') ? '<div class="text-center hidden-xs hidden-sm"><input type="checkbox" name="edit_user['.e($user->id).']" class="one_required"></div>' : '',
'name' => '<a title="'.e($user->fullName()).'" href="../admin/users/'.e($user->id).'/view">'.e($user->fullName()).'</a>',
'name' => '<a title="'.e($user->fullName()).'" href="'.config('app.url').'/admin/users/'.e($user->id).'/view">'.e($user->fullName()).'</a>',
'jobtitle' => e($user->jobtitle),
'email' => ($user->email!='') ?
'<a href="mailto:'.e($user->email).'" class="hidden-md hidden-lg">'.e($user->email).'</a>'
@ -986,7 +1023,7 @@ class UsersController extends Controller
.'</span>' : '',
'username' => e($user->username),
'location' => ($user->userloc) ? e($user->userloc->name) : '',
'manager' => ($user->manager) ? '<a title="' . e($user->manager->fullName()) . '" href="users/' . e($user->manager->id) . '/view">' . e($user->manager->fullName()) . '</a>' : '',
'manager' => ($user->manager) ? '<a title="' . e($user->manager->fullName()) . '" href="'.config('app.url').'/' . e($user->manager->id) . '/view">' . e($user->manager->fullName()) . '</a>' : '',
'assets' => $user->assets->count(),
'employee_num' => e($user->employee_num),
'licenses' => $user->licenses->count(),
@ -994,8 +1031,10 @@ class UsersController extends Controller
'consumables' => $user->consumables->count(),
'groups' => $group_names,
'notes' => e($user->notes),
'two_factor_enrolled' => ($user->two_factor_enrolled=='1') ? '<i class="fa fa-check text-success"></i>' : '<i class="fa fa-times text-danger"></i>',
'two_factor_optin' => (($user->two_factor_optin=='1') || (Setting::getSettings()->two_factor_enabled=='2') ) ? '<i class="fa fa-check text-success"></i>' : '<i class="fa fa-times text-danger"></i>',
'created_at' => ($user->created_at!='') ? e($user->created_at->format('F j, Y h:iA')) : '',
'activated' => ($user->activated=='1') ? '<i class="fa fa-check"></i>' : '<i class="fa fa-times"></i>',
'activated' => ($user->activated=='1') ? '<i class="fa fa-check text-success"></i>' : '<i class="fa fa-times text-danger"></i>',
'actions' => ($actions) ? $actions : '',
'companyName' => is_null($user->company) ? '' : e($user->company->name)
);
@ -1365,4 +1404,25 @@ class UsersController extends Controller
return $response;
}
public function postTwoFactorReset(Request $request)
{
if (Gate::denies('users.edit')) {
return response()->json(['message' => trans('general.insufficient_permissions')], 500);
}
try {
$user = User::find($request->get('id'));
$user->two_factor_secret = null;
$user->two_factor_enrolled = 0;
$user->save();
return response()->json(['message' => trans('admin/settings/general.two_factor_reset_success')], 200);
} catch (\Exception $e) {
return response()->json(['message' => trans('admin/settings/general.two_factor_reset_error')], 500);
}
}
}

View file

@ -22,6 +22,7 @@ use Redirect;
use Slack;
use Validator;
use View;
use Illuminate\Http\Request;
/**
* This controller handles all actions related to the ability for users
@ -294,10 +295,14 @@ class ViewAssetsController extends Controller
//return redirect()->to('account')->with('error', trans('admin/hardware/message.does_not_exist'));
}
if ($findlog->accepted_id!='') {
return redirect()->to('account/view-assets')->with('error', trans('admin/users/message.error.asset_already_accepted'));
}
$user = Auth::user();
if ($user->id != $findlog->checkedout_to) {
if ($user->id != $findlog->item->assigned_to) {
return redirect()->to('account/view-assets')->with('error', trans('admin/users/message.error.incorrect_user_accepted'));
}
@ -310,12 +315,12 @@ class ViewAssetsController extends Controller
} elseif (!Company::isCurrentUserHasAccess($item)) {
return redirect()->route('requestable-assets')->with('error', trans('general.insufficient_permissions'));
} else {
return View::make('account/accept-asset', compact('item'))->with('findlog', $findlog);
return View::make('account/accept-asset', compact('item'))->with('findlog', $findlog)->with('item',$item);
}
}
// Save the acceptance
public function postAcceptAsset($logID = null)
public function postAcceptAsset(Request $request, $logID = null)
{
// Check if the asset exists
@ -331,15 +336,25 @@ class ViewAssetsController extends Controller
}
if (!Input::has('asset_acceptance')) {
return redirect()->to('account/view-assets')->with('error', trans('admin/users/message.error.accept_or_decline'));
return redirect()->back()->with('error', trans('admin/users/message.error.accept_or_decline'));
}
$user = Auth::user();
if ($user->id != $findlog->checkedout_to) {
if ($user->id != $findlog->item->assigned_to) {
return redirect()->to('account/view-assets')->with('error', trans('admin/users/message.error.incorrect_user_accepted'));
}
if ($request->has('signature_output')) {
$path = config('app.private_uploads').'/signatures';
$sig_filename = "siglog-".$findlog->id.'-'.date('Y-m-d-his').".png";
$data_uri = e($request->get('signature_output'));
$encoded_image = explode(",", $data_uri);
$decoded_image = base64_decode($encoded_image[1]);
file_put_contents($path."/".$sig_filename, $decoded_image);
}
$logaction = new Actionlog();
if (Input::get('asset_acceptance')=='accepted') {
@ -353,6 +368,7 @@ class ViewAssetsController extends Controller
}
$logaction->item_id = $findlog->item_id;
$logaction->item_type = $findlog->item_type;
// Asset
if (($findlog->item_id!='') && ($findlog->item_type==Asset::class)) {
if (Input::get('asset_acceptance')!='accepted') {
@ -361,19 +377,23 @@ class ViewAssetsController extends Controller
->update(array('assigned_to' => null));
}
}
$logaction->target_id = $findlog->target_id;
$logaction->target_id = $findlog->target_id;
$logaction->note = e(Input::get('note'));
$logaction->user_id = $user->id;
$logaction->accepted_at = date("Y-m-d H:i:s");
$logaction->updated_at = date("Y-m-d H:i:s");
if ($sig_filename) {
$logaction->accept_signature = $sig_filename;
}
$log = $logaction->logaction($logaction_msg);
$update_checkout = DB::table('action_logs')
->where('id', $findlog->id)
->update(array('accepted_id' => $logaction->id));
$affected_asset=$logaction->assetlog;
$affected_asset->accepted=$accepted;
$affected_asset = $logaction->item;
$affected_asset->accepted = $accepted;
$affected_asset->save();
if ($update_checkout) {

View file

@ -35,6 +35,7 @@ class Kernel extends HttpKernel
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\App\Http\Middleware\CheckLocale::class,
\App\Http\Middleware\CheckForTwoFactor::class,
],
'api' => [

View file

@ -0,0 +1,52 @@
<?php
namespace App\Http\Middleware;
use App\Models\Setting;
use Auth;
use Closure;
use Illuminate\Support\Facades\Schema;
use Log;
class CheckForTwoFactor
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
// Skip the logic if the user is on the two factor pages
if (($request->route()->getName()=='two-factor') || ($request->route()->getName()=='two-factor-enroll') || ($request->route()->getName()=='logout')) {
return $next($request);
}
// Two-factor is enabled (either optional or required)
if (Schema::hasTable('settings')) {
if (Auth::check() && (Setting::getSettings()->two_factor_enabled!='')) {
// This user is already 2fa-authed
if ($request->session()->get('2fa_authed')) {
return $next($request);
}
// Two-factor is optional and the user has NOT opted in, let them through
if ((Setting::getSettings()->two_factor_enabled=='1') && (Auth::user()->two_factor_optin!='1')) {
return $next($request);
}
// Otherwise make sure they're enrolled and show them the 2FA code screen
if ((Auth::user()->two_factor_secret!='') && (Auth::user()->two_factor_enrolled=='1')) {
return redirect()->route('two-factor')->with('info', 'Please enter your two-factor authentication code.');
}
return redirect()->route('two-factor-enroll')->with('success', 'Please enroll a device in two-factor authentication.');
}
}
return $next($request);
}
}

View file

@ -22,7 +22,8 @@ class CheckPermissions
*/
public function handle($request, Closure $next, $section = null)
{
if (Gate::allows($section)) {
return $next($request);
}

View file

@ -18,7 +18,7 @@ class RedirectIfAuthenticated
public function handle($request, Closure $next, $guard = null)
{
if (Auth::guard($guard)->check()) {
return redirect('/');
return redirect()->intended('/');
}
return $next($request);

View file

@ -90,6 +90,7 @@ Route::group([ 'prefix' => 'api', 'middleware' => 'auth' ], function () {
/*---Users API---*/
Route::group([ 'prefix' => 'users' ], function () {
Route::post('/', [ 'as' => 'api.users.store', 'uses' => 'UsersController@store' ]);
Route::post('two_factor_reset', [ 'as' => 'api.users.two_factor_reset', 'uses' => 'UsersController@postTwoFactorReset' ]);
Route::get('list/{status?}', [ 'as' => 'api.users.list', 'uses' => 'UsersController@getDatatable' ]);
Route::get('{userId}/assets', [ 'as' => 'api.users.assetlist', 'uses' => 'UsersController@getAssetList' ]);
Route::post('{userId}/upload', [ 'as' => 'upload/user', 'uses' => 'UsersController@postUpload' ]);
@ -378,6 +379,30 @@ Route::group(
}
);
/*
|--------------------------------------------------------------------------
| Log Routes
|--------------------------------------------------------------------------
|
| Register all the admin routes.
|
*/
Route::group(['middleware' => 'auth'], function () {
Route::get(
'display-sig/{filename}',
[
'as' => 'log.signature.view',
'middleware' => 'authorize:assets.view',
'uses' => 'ActionlogController@displaySig' ]
);
});
/*
|--------------------------------------------------------------------------
| Admin Routes
@ -997,6 +1022,29 @@ Route::group([ 'prefix' => 'setup', 'middleware' => 'web'], function () {
});
Route::get(
'two-factor-enroll',
[
'as' => 'two-factor-enroll',
'middleware' => ['web'],
'uses' => 'Auth\AuthController@getTwoFactorEnroll' ]
);
Route::get(
'two-factor',
[
'as' => 'two-factor',
'middleware' => ['web'],
'uses' => 'Auth\AuthController@getTwoFactorAuth' ]
);
Route::post(
'two-factor',
[
'as' => 'two-factor',
'middleware' => ['web'],
'uses' => 'Auth\AuthController@postTwoFactorAuth' ]
);
Route::get(
'/',
@ -1006,8 +1054,24 @@ Route::get(
'uses' => 'DashboardController@getIndex' ]
);
Route::group(['middleware' => 'web'], function () {
Route::auth();
Route::get(
'login',
[
'as' => 'login',
'middleware' => ['web'],
'uses' => 'Auth\AuthController@showLoginForm' ]
);
Route::get(
'logout',
[
'as' => 'logout',
'uses' => 'Auth\AuthController@logout' ]
);
});
Route::get('home', function () {

View file

@ -28,7 +28,7 @@ class Accessory extends Model
'qty' => 'required|integer|min:1',
'category_id' => 'required|integer',
'company_id' => 'integer',
'min_amt' => 'integer|min:1',
'min_amt' => 'integer|min:0',
'purchase_cost' => 'numeric',
);

View file

@ -4,8 +4,7 @@ namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Response;
/**
* Model for the Actionlog (the table that keeps a historical log of
@ -46,6 +45,10 @@ class Actionlog extends Model
return $this->morphTo('item')->withTrashed();
}
public function company() {
return $this->hasMany('\App\Models\Company', 'id','company_id');
}
public function itemType()
{
@ -91,15 +94,14 @@ class Actionlog extends Model
/**
* Check if the file exists, and if it does, force a download
**/
public function get_src($type = 'assets')
public function get_src($type = 'assets', $fieldname = 'filename')
{
$file = config('app.private_uploads') . '/' . $type . '/' . $this->filename;
$file = config('app.private_uploads') . '/' . $type . '/' . $this->{$fieldname};
return $file;
}
/**
* Get the parent category name
*/
@ -131,4 +133,30 @@ class Actionlog extends Model
->orderBy('created_at', 'asc')
->get();
}
/**
* Query builder scope to search on text for complex Bootstrap Tables API
*
* @param Illuminate\Database\Query\Builder $query Query builder instance
* @param text $search Search term
*
* @return Illuminate\Database\Query\Builder Modified query builder
*/
public function scopeTextSearch($query, $search)
{
$search = explode(' OR ', $search);
return $query->where(function ($query) use ($search) {
foreach ($search as $search) {
$query->where(function ($query) use ($search) {
$query->whereHas('company', function ($query) use ($search) {
$query->where('companies.name', 'LIKE', '%'.$search.'%');
});
})->orWhere('action_type', 'LIKE', '%'.$search.'%')
->orWhere('note', 'LIKE', '%'.$search.'%');
}
});
}
}

View file

@ -860,17 +860,17 @@ public function checkin_email()
}
/**
* Query builder scope to order on assigned user
*
* @param Illuminate\Database\Query\Builder $query Query builder instance
* @param text $order Order
*
* @return Illuminate\Database\Query\Builder Modified query builder
*/
/**
* Query builder scope to order on assigned user
*
* @param Illuminate\Database\Query\Builder $query Query builder instance
* @param text $order Order
*
* @return Illuminate\Database\Query\Builder Modified query builder
*/
public function scopeOrderAssigned($query, $order)
{
return $query->join('users', 'assets.assigned_to', '=', 'users.id')->orderBy('users.first_name', $order)->orderBy('users.last_name', $order);
return $query->leftJoin('users', 'assets.assigned_to', '=', 'users.id')->select('assets.*')->orderBy('users.first_name', $order)->orderBy('users.last_name', $order);
}
/**

View file

@ -222,7 +222,7 @@ class Ldap extends Model
return true;
} else {
LOG::debug('Could not create user.'.$user->getErrors());
exit;
throw new Exception("Could not create user: ".$user->getErrors());
}
}

View file

@ -101,6 +101,20 @@ class License extends Depreciable
->count();
}
// We do this to eager load the "count" of seats from the controller. Otherwise calling "count()" on each model results in n+1
public function licenseSeatsRelation()
{
return $this->hasMany(LicenseSeat::class)->whereNull('deleted_at')->selectRaw('license_id, count(*) as count')->groupBy('license_id');
}
public function getLicenseSeatsCountAttribute()
{
if ($this->licenseSeatsRelation->first()) {
return $this->licenseSeatsRelation->first()->count;
}
return 0;
}
/**
* Get total licenses not checked out
@ -116,37 +130,47 @@ class License extends Depreciable
/**
* Get the number of available seats
*/
public function availcount()
public function availCount()
{
return LicenseSeat::whereNull('assigned_to')
->whereNull('asset_id')
->where('license_id', '=', $this->id)
->whereNull('deleted_at')
->count();
return $this->licenseSeatsRelation()
->whereNull('asset_id');
}
public function getAvailSeatsCountAttribute()
{
if ($this->availCount->first()) {
return $this->availCount->first()->count;
}
return 0;
}
/**
* Get the number of assigned seats
*
*/
public function assignedcount()
public function assignedCount()
{
return $this->licenseSeatsRelation()->where(function ($query) {
$query->whereNotNull('assigned_to')
->orWhereNotNull('asset_id');
});
}
return \App\Models\LicenseSeat::where('license_id', '=', $this->id)
->where(function ($query) {
$query->whereNotNull('assigned_to')
->orWhereNotNull('asset_id');
})
->count();
public function getAssignedSeatsCountAttribute()
{
// dd($this->licenseSeatsRelation->first());
if ($this->assignedCount->first()) {
return $this->assignedCount->first()->count;
}
return 0;
}
public function remaincount()
{
$total = $this->totalSeatsByLicenseID();
$taken = $this->assignedcount();
$total = $this->licenseSeatsCount;
$taken = $this->assigned_seats;
$diff = ($total - $taken);
return $diff;
}
@ -156,7 +180,7 @@ class License extends Depreciable
*/
public function totalcount()
{
$avail = $this->availcount();
$avail = $this->availSeatsCount;
$taken = $this->assignedcount();
$diff = ($avail + $taken);
return $diff;
@ -210,13 +234,51 @@ class License extends Depreciable
return $query->where(function ($query) use ($search) {
$query->where('name', 'LIKE', '%'.$search.'%')
->orWhere('serial', 'LIKE', '%'.$search.'%')
->orWhere('notes', 'LIKE', '%'.$search.'%')
->orWhere('order_number', 'LIKE', '%'.$search.'%')
->orWhere('purchase_order', 'LIKE', '%'.$search.'%')
->orWhere('purchase_date', 'LIKE', '%'.$search.'%')
->orWhere('purchase_cost', 'LIKE', '%'.$search.'%');
$query->where('licenses.name', 'LIKE', '%'.$search.'%')
->orWhere('licenses.serial', 'LIKE', '%'.$search.'%')
->orWhere('licenses.notes', 'LIKE', '%'.$search.'%')
->orWhere('licenses.order_number', 'LIKE', '%'.$search.'%')
->orWhere('licenses.purchase_order', 'LIKE', '%'.$search.'%')
->orWhere('licenses.purchase_date', 'LIKE', '%'.$search.'%')
->orWhere('licenses.purchase_cost', 'LIKE', '%'.$search.'%')
->orWhereHas('manufacturer', function ($query) use ($search) {
$query->where(function ($query) use ($search) {
$query->where('manufacturers.name', 'LIKE', '%'.$search.'%');
});
})
->orWhereHas('company', function ($query) use ($search) {
$query->where(function ($query) use ($search) {
$query->where('companies.name', 'LIKE', '%'.$search.'%');
});
});
});
}
/**
* Query builder scope to order on manufacturer
*
* @param Illuminate\Database\Query\Builder $query Query builder instance
* @param text $order Order
*
* @return Illuminate\Database\Query\Builder Modified query builder
*/
public function scopeOrderManufacturer($query, $order)
{
return $query->leftJoin('manufacturers', 'licenses.manufacturer_id', '=', 'manufacturers.id')->select('licenses.*')
->orderBy('manufacturers.name', $order);
}
/**
* Query builder scope to order on company
*
* @param Illuminate\Database\Query\Builder $query Query builder instance
* @param text $order Order
*
* @return Illuminate\Database\Query\Builder Modified query builder
*/
public function scopeOrderCompany($query, $order)
{
return $query->leftJoin('companies as companies', 'licenses.company_id', '=', 'companies.id')->select('licenses.*')
->orderBy('companies.name', $order);
}
}

View file

@ -47,6 +47,21 @@ class Supplier extends Model
protected $fillable = ['name'];
// Eager load counts.
// We do this to eager load the "count" of seats from the controller. Otherwise calling "count()" on each model results in n+1
public function assetsRelation()
{
return $this->hasMany(Asset::class)->whereNull('deleted_at')->selectRaw('supplier_id, count(*) as count')->groupBy('supplier_id');
}
public function getLicenseSeatsCountAttribute()
{
if ($this->licenseSeatsRelation->first()) {
return $this->licenseSeatsRelation->first()->count;
}
return 0;
}
public function assets()
{
return $this->hasMany('\App\Models\Asset', 'supplier_id');
@ -59,7 +74,11 @@ class Supplier extends Model
public function num_assets()
{
return $this->hasMany('\App\Models\Asset', 'supplier_id')->count();
if ($this->assetsRelation->first()) {
return $this->assetsRelation->first()->count;
}
return 0;
}
public function licenses()
@ -69,7 +88,7 @@ class Supplier extends Model
public function num_licenses()
{
return $this->hasMany('\App\Models\License', 'supplier_id')->count();
return $this->licenses()->count();
}
public function addhttp($url)

View file

@ -389,6 +389,11 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon
$query->where('locations.name', 'LIKE', '%'.$search.'%');
});
})
->orWhere(function ($query) use ($search) {
$query->whereHas('groups', function ($query) use ($search) {
$query->where('groups.name', 'LIKE', '%'.$search.'%');
});
})
// Ugly, ugly code because Laravel sucks at self-joins
->orWhere(function ($query) use ($search) {

View file

@ -328,5 +328,15 @@ class AuthServiceProvider extends ServiceProvider
});
# -----------------------------------------
# Self
# -----------------------------------------
$gate->define('self.two_factor', function ($user) {
if (($user->hasAccess('self.two_factor')) || ($user->hasAccess('admin'))) {
return true;
}
});
}
}

View file

@ -23,7 +23,8 @@
"barryvdh/laravel-debugbar": "^2.1",
"spatie/laravel-backup": "3.8.1",
"misterphilip/maintenance-mode": "1.0.*",
"neitanod/forceutf8": "dev-master"
"neitanod/forceutf8": "dev-master",
"pragmarx/google2fa": "^1.0"
},
"require-dev": {
"fzaninotto/faker": "~1.4",

119
composer.lock generated
View file

@ -4,8 +4,8 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
"hash": "ed9f8700f2dcd943ff662a82e4d8314f",
"content-hash": "9c0251ddc1a110d83a762483abeea079",
"hash": "a188b3cf19debb9f4ad80016cb02bacd",
"content-hash": "d05155478c07249acdb2fed3d47189e6",
"packages": [
{
"name": "aws/aws-sdk-php",
@ -197,6 +197,60 @@
],
"time": "2016-07-29 15:00:36"
},
{
"name": "christian-riesen/base32",
"version": "1.3.1",
"source": {
"type": "git",
"url": "https://github.com/ChristianRiesen/base32.git",
"reference": "0a31e50c0fa9b1692d077c86ac188eecdcbaf7fa"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/ChristianRiesen/base32/zipball/0a31e50c0fa9b1692d077c86ac188eecdcbaf7fa",
"reference": "0a31e50c0fa9b1692d077c86ac188eecdcbaf7fa",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"require-dev": {
"phpunit/phpunit": "4.*",
"satooshi/php-coveralls": "0.*"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.1.x-dev"
}
},
"autoload": {
"psr-4": {
"Base32\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Christian Riesen",
"email": "chris.riesen@gmail.com",
"homepage": "http://christianriesen.com",
"role": "Developer"
}
],
"description": "Base32 encoder/decoder according to RFC 4648",
"homepage": "https://github.com/ChristianRiesen/base32",
"keywords": [
"base32",
"decode",
"encode",
"rfc4648"
],
"time": "2016-05-05 11:49:03"
},
{
"name": "classpreloader/classpreloader",
"version": "3.0.0",
@ -2056,6 +2110,67 @@
],
"time": "2016-03-18 20:34:03"
},
{
"name": "pragmarx/google2fa",
"version": "v1.0.1",
"source": {
"type": "git",
"url": "https://github.com/antonioribeiro/google2fa.git",
"reference": "b346dc138339b745c5831405d00cff7c1351aa0d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/antonioribeiro/google2fa/zipball/b346dc138339b745c5831405d00cff7c1351aa0d",
"reference": "b346dc138339b745c5831405d00cff7c1351aa0d",
"shasum": ""
},
"require": {
"christian-riesen/base32": "~1.3",
"paragonie/random_compat": "~1.4|~2.0",
"php": ">=5.4",
"symfony/polyfill-php56": "~1.2"
},
"require-dev": {
"phpspec/phpspec": "~2.1"
},
"suggest": {
"bacon/bacon-qr-code": "Required to generate inline QR Codes."
},
"type": "library",
"extra": {
"component": "package",
"frameworks": [
"Laravel"
],
"branch-alias": {
"dev-master": "1.0-dev"
}
},
"autoload": {
"psr-4": {
"PragmaRX\\Google2FA\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Antonio Carlos Ribeiro",
"email": "acr@antoniocarlosribeiro.com",
"role": "Creator & Designer"
}
],
"description": "A One Time Password Authentication package, compatible with Google Authenticator.",
"keywords": [
"Authentication",
"Two Factor Authentication",
"google2fa",
"laravel"
],
"time": "2016-07-18 20:25:04"
},
{
"name": "psr/http-message",
"version": "1.0.1",

View file

@ -212,7 +212,7 @@ return [
Fideloper\Proxy\TrustedProxyServiceProvider::class,
MisterPhilip\MaintenanceMode\MaintenanceModeServiceProvider::class,
MisterPhilip\MaintenanceMode\MaintenanceCommandServiceProvider::class,
PragmaRX\Google2FA\Vendor\Laravel\ServiceProvider::class,
/*
* Custom service provider
*/
@ -269,6 +269,7 @@ return [
'View' => Illuminate\Support\Facades\View::class,
'Form' => 'Collective\Html\FormFacade',
'Html' => 'Collective\Html\HtmlFacade',
'Google2FA' => PragmaRX\Google2FA\Vendor\Laravel\Facade::class,
],
];

View file

@ -279,6 +279,16 @@ return array(
),
'Self' => array(
array(
'permission' => 'self.two_factor',
'label' => 'Two-Factor Authentication',
'note' => 'The user may disable/enable two-factor authentication themselves if two-factor is enabled and set to selective.',
'display' => true,
),
),

View file

@ -1,5 +1,5 @@
<?php
return array (
'app_version' => 'v3.5.2',
'hash_version' => 'v3.5.2-11-g5a835a5',
'app_version' => 'v3.6.0-pre',
'hash_version' => 'v3.6.0-pre-41-ga914dac',
);

View file

@ -59,6 +59,7 @@ class MigrateAssetLogToActionLog extends Migration
$a->expected_checkin = $log->expected_checkin;
$a->thread_id = $log->thread_id;
$a->accepted_id = $log->accepted_id;
$a->filename = $log->filename;
$a->save();

View file

@ -0,0 +1,43 @@
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class Enable2faFields extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('settings', function ($table) {
$table->tinyInteger('two_factor_enabled')->nullable()->default(null);
});
Schema::table('users', function ($table) {
$table->string('two_factor_secret', 32)->nullable()->default(null);
$table->boolean('two_factor_enrolled')->default(0);
$table->boolean('two_factor_optin')->default(0);
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('settings', function ($table) {
$table->dropColumn('two_factor_enabled');
});
Schema::table('users', function ($table) {
$table->dropColumn('two_factor_secret');
$table->dropColumn('two_factor_enrolled');
$table->dropColumn('two_factor_optin');
});
}
}

View file

@ -0,0 +1,39 @@
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddSignatureToAcceptance extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('settings', function ($table) {
$table->boolean('require_accept_signature')->default(0);
});
Schema::table('action_logs', function ($table) {
$table->string('accept_signature', 100)->nullable()->default(null);
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('settings', function ($table) {
$table->dropColumn('require_accept_signature');
});
Schema::table('action_logs', function ($table) {
$table->dropColumn('accept_signature');
});
}
}

View file

@ -0,0 +1,53 @@
<?php
use App\Models\Actionlog;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class FixForgottenFilenameInActionLogs extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('action_logs', function (Blueprint $table) {
$logs = DB::table('asset_logs')->where('filename', '!=', null)->get();
//
foreach($logs as $log) {
$matching_action_log = Actionlog::where('item_id', $log->asset_id)
->where('created_at', $log->created_at)
->where('note', $log->note)
->where('filename', null)
->withTrashed()
->get()->first();
if($matching_action_log) {
$matching_action_log->filename = $log->filename;
$matching_action_log->save();
}else{
echo("Couldn't find matching Action log row when trying to migrate".
" filename from asset log:\n".
"LogDate{$log->created_at} LogForAsset:{$log->asset_id}".
"LogNote:{$log->note} \n");
}
}
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('action_logs', function (Blueprint $table) {
//
});
}
}

View file

@ -0,0 +1,136 @@
#signature-pad {
padding-top: 250px;
margin: auto;
}
.m-signature-pad {
position: relative;
font-size: 10px;
width: 100%;
height: 300px;
border: 1px solid #e8e8e8;
background-color: #fff;
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.27), 0 0 40px rgba(0, 0, 0, 0.08) inset;
border-radius: 4px;
}
.m-signature-pad:before, .m-signature-pad:after {
position: absolute;
z-index: -1;
content: "";
width: 40%;
height: 10px;
left: 20px;
bottom: 10px;
background: transparent;
-webkit-transform: skew(-3deg) rotate(-3deg);
-moz-transform: skew(-3deg) rotate(-3deg);
-ms-transform: skew(-3deg) rotate(-3deg);
-o-transform: skew(-3deg) rotate(-3deg);
transform: skew(-3deg) rotate(-3deg);
box-shadow: 0 8px 12px rgba(0, 0, 0, 0.4);
}
.m-signature-pad:after {
left: auto;
right: 20px;
-webkit-transform: skew(3deg) rotate(3deg);
-moz-transform: skew(3deg) rotate(3deg);
-ms-transform: skew(3deg) rotate(3deg);
-o-transform: skew(3deg) rotate(3deg);
transform: skew(3deg) rotate(3deg);
}
.m-signature-pad--body {
position: absolute;
left: 20px;
right: 20px;
top: 20px;
bottom: 60px;
border: 1px solid #f4f4f4;
}
.m-signature-pad--body
canvas {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
border-radius: 4px;
box-shadow: 0 0 5px rgba(0, 0, 0, 0.02) inset;
}
.m-signature-pad--footer {
position: absolute;
left: 20px;
right: 20px;
bottom: 20px;
height: 40px;
}
.m-signature-pad--footer
.description {
color: #C3C3C3;
text-align: center;
font-size: 1.2em;
margin-top: 1.8em;
}
.m-signature-pad--footer
.button {
position: absolute;
bottom: 0;
}
.m-signature-pad--footer
.button.clear {
left: 0;
}
.m-signature-pad--footer
.button.save {
right: 0;
}
@media screen and (max-width: 1024px) {
.m-signature-pad {
top: 0;
left: 0;
right: 0;
bottom: 0;
width: auto;
height: auto;
min-width: 250px;
min-height: 140px;
margin: 5%;
}
}
@media screen and (min-device-width: 768px) and (max-device-width: 1024px) {
.m-signature-pad {
margin: 10%;
}
}
@media screen and (max-height: 320px) {
.m-signature-pad--body {
left: 0;
right: 0;
top: 0;
bottom: 32px;
}
.m-signature-pad--footer {
left: 20px;
right: 20px;
bottom: 4px;
height: 28px;
}
.m-signature-pad--footer
.description {
font-size: 1em;
margin-top: 1em;
}
}

389
public/assets/js/signature_pad.js Executable file
View file

@ -0,0 +1,389 @@
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module unless amdModuleId is set
define([], function () {
return (root['SignaturePad'] = factory());
});
} else if (typeof exports === 'object') {
// Node. Does not work with strict CommonJS, but
// only CommonJS-like environments that support module.exports,
// like Node.
module.exports = factory();
} else {
root['SignaturePad'] = factory();
}
}(this, function () {
/*!
* Signature Pad v1.5.3
* https://github.com/szimek/signature_pad
*
* Copyright 2016 Szymon Nowak
* Released under the MIT license
*
* The main idea and some parts of the code (e.g. drawing variable width Bézier curve) are taken from:
* http://corner.squareup.com/2012/07/smoother-signatures.html
*
* Implementation of interpolation using cubic Bézier curves is taken from:
* http://benknowscode.wordpress.com/2012/09/14/path-interpolation-using-cubic-bezier-and-control-point-estimation-in-javascript
*
* Algorithm for approximated length of a Bézier curve is taken from:
* http://www.lemoda.net/maths/bezier-length/index.html
*
*/
var SignaturePad = (function (document) {
"use strict";
var SignaturePad = function (canvas, options) {
var self = this,
opts = options || {};
this.velocityFilterWeight = opts.velocityFilterWeight || 0.7;
this.minWidth = opts.minWidth || 0.5;
this.maxWidth = opts.maxWidth || 2.5;
this.dotSize = opts.dotSize || function () {
return (this.minWidth + this.maxWidth) / 2;
};
this.penColor = opts.penColor || "black";
this.backgroundColor = opts.backgroundColor || "rgba(0,0,0,0)";
this.onEnd = opts.onEnd;
this.onBegin = opts.onBegin;
this._canvas = canvas;
this._ctx = canvas.getContext("2d");
this.clear();
// we need add these inline so they are available to unbind while still having
// access to 'self' we could use _.bind but it's not worth adding a dependency
this._handleMouseDown = function (event) {
if (event.which === 1) {
self._mouseButtonDown = true;
self._strokeBegin(event);
}
};
this._handleMouseMove = function (event) {
if (self._mouseButtonDown) {
self._strokeUpdate(event);
}
};
this._handleMouseUp = function (event) {
if (event.which === 1 && self._mouseButtonDown) {
self._mouseButtonDown = false;
self._strokeEnd(event);
}
};
this._handleTouchStart = function (event) {
if (event.targetTouches.length == 1) {
var touch = event.changedTouches[0];
self._strokeBegin(touch);
}
};
this._handleTouchMove = function (event) {
// Prevent scrolling.
event.preventDefault();
var touch = event.targetTouches[0];
self._strokeUpdate(touch);
};
this._handleTouchEnd = function (event) {
var wasCanvasTouched = event.target === self._canvas;
if (wasCanvasTouched) {
event.preventDefault();
self._strokeEnd(event);
}
};
this._handleMouseEvents();
this._handleTouchEvents();
};
SignaturePad.prototype.clear = function () {
var ctx = this._ctx,
canvas = this._canvas;
ctx.fillStyle = this.backgroundColor;
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillRect(0, 0, canvas.width, canvas.height);
this._reset();
};
SignaturePad.prototype.toDataURL = function (imageType, quality) {
var canvas = this._canvas;
return canvas.toDataURL.apply(canvas, arguments);
};
SignaturePad.prototype.fromDataURL = function (dataUrl) {
var self = this,
image = new Image(),
ratio = window.devicePixelRatio || 1,
width = this._canvas.width / ratio,
height = this._canvas.height / ratio;
this._reset();
image.src = dataUrl;
image.onload = function () {
self._ctx.drawImage(image, 0, 0, width, height);
};
this._isEmpty = false;
};
SignaturePad.prototype._strokeUpdate = function (event) {
var point = this._createPoint(event);
this._addPoint(point);
};
SignaturePad.prototype._strokeBegin = function (event) {
this._reset();
this._strokeUpdate(event);
if (typeof this.onBegin === 'function') {
this.onBegin(event);
}
};
SignaturePad.prototype._strokeDraw = function (point) {
var ctx = this._ctx,
dotSize = typeof(this.dotSize) === 'function' ? this.dotSize() : this.dotSize;
ctx.beginPath();
this._drawPoint(point.x, point.y, dotSize);
ctx.closePath();
ctx.fill();
};
SignaturePad.prototype._strokeEnd = function (event) {
var canDrawCurve = this.points.length > 2,
point = this.points[0];
if (!canDrawCurve && point) {
this._strokeDraw(point);
}
if (typeof this.onEnd === 'function') {
this.onEnd(event);
}
};
SignaturePad.prototype._handleMouseEvents = function () {
this._mouseButtonDown = false;
this._canvas.addEventListener("mousedown", this._handleMouseDown);
this._canvas.addEventListener("mousemove", this._handleMouseMove);
document.addEventListener("mouseup", this._handleMouseUp);
};
SignaturePad.prototype._handleTouchEvents = function () {
// Pass touch events to canvas element on mobile IE11 and Edge.
this._canvas.style.msTouchAction = 'none';
this._canvas.style.touchAction = 'none';
this._canvas.addEventListener("touchstart", this._handleTouchStart);
this._canvas.addEventListener("touchmove", this._handleTouchMove);
this._canvas.addEventListener("touchend", this._handleTouchEnd);
};
SignaturePad.prototype.on = function () {
this._handleMouseEvents();
this._handleTouchEvents();
};
SignaturePad.prototype.off = function () {
this._canvas.removeEventListener("mousedown", this._handleMouseDown);
this._canvas.removeEventListener("mousemove", this._handleMouseMove);
document.removeEventListener("mouseup", this._handleMouseUp);
this._canvas.removeEventListener("touchstart", this._handleTouchStart);
this._canvas.removeEventListener("touchmove", this._handleTouchMove);
this._canvas.removeEventListener("touchend", this._handleTouchEnd);
};
SignaturePad.prototype.isEmpty = function () {
return this._isEmpty;
};
SignaturePad.prototype._reset = function () {
this.points = [];
this._lastVelocity = 0;
this._lastWidth = (this.minWidth + this.maxWidth) / 2;
this._isEmpty = true;
this._ctx.fillStyle = this.penColor;
};
SignaturePad.prototype._createPoint = function (event) {
var rect = this._canvas.getBoundingClientRect();
return new Point(
event.clientX - rect.left,
event.clientY - rect.top
);
};
SignaturePad.prototype._addPoint = function (point) {
var points = this.points,
c2, c3,
curve, tmp;
points.push(point);
if (points.length > 2) {
// To reduce the initial lag make it work with 3 points
// by copying the first point to the beginning.
if (points.length === 3) points.unshift(points[0]);
tmp = this._calculateCurveControlPoints(points[0], points[1], points[2]);
c2 = tmp.c2;
tmp = this._calculateCurveControlPoints(points[1], points[2], points[3]);
c3 = tmp.c1;
curve = new Bezier(points[1], c2, c3, points[2]);
this._addCurve(curve);
// Remove the first element from the list,
// so that we always have no more than 4 points in points array.
points.shift();
}
};
SignaturePad.prototype._calculateCurveControlPoints = function (s1, s2, s3) {
var dx1 = s1.x - s2.x, dy1 = s1.y - s2.y,
dx2 = s2.x - s3.x, dy2 = s2.y - s3.y,
m1 = {x: (s1.x + s2.x) / 2.0, y: (s1.y + s2.y) / 2.0},
m2 = {x: (s2.x + s3.x) / 2.0, y: (s2.y + s3.y) / 2.0},
l1 = Math.sqrt(dx1*dx1 + dy1*dy1),
l2 = Math.sqrt(dx2*dx2 + dy2*dy2),
dxm = (m1.x - m2.x),
dym = (m1.y - m2.y),
k = l2 / (l1 + l2),
cm = {x: m2.x + dxm*k, y: m2.y + dym*k},
tx = s2.x - cm.x,
ty = s2.y - cm.y;
return {
c1: new Point(m1.x + tx, m1.y + ty),
c2: new Point(m2.x + tx, m2.y + ty)
};
};
SignaturePad.prototype._addCurve = function (curve) {
var startPoint = curve.startPoint,
endPoint = curve.endPoint,
velocity, newWidth;
velocity = endPoint.velocityFrom(startPoint);
velocity = this.velocityFilterWeight * velocity
+ (1 - this.velocityFilterWeight) * this._lastVelocity;
newWidth = this._strokeWidth(velocity);
this._drawCurve(curve, this._lastWidth, newWidth);
this._lastVelocity = velocity;
this._lastWidth = newWidth;
};
SignaturePad.prototype._drawPoint = function (x, y, size) {
var ctx = this._ctx;
ctx.moveTo(x, y);
ctx.arc(x, y, size, 0, 2 * Math.PI, false);
this._isEmpty = false;
};
SignaturePad.prototype._drawCurve = function (curve, startWidth, endWidth) {
var ctx = this._ctx,
widthDelta = endWidth - startWidth,
drawSteps, width, i, t, tt, ttt, u, uu, uuu, x, y;
drawSteps = Math.floor(curve.length());
ctx.beginPath();
for (i = 0; i < drawSteps; i++) {
// Calculate the Bezier (x, y) coordinate for this step.
t = i / drawSteps;
tt = t * t;
ttt = tt * t;
u = 1 - t;
uu = u * u;
uuu = uu * u;
x = uuu * curve.startPoint.x;
x += 3 * uu * t * curve.control1.x;
x += 3 * u * tt * curve.control2.x;
x += ttt * curve.endPoint.x;
y = uuu * curve.startPoint.y;
y += 3 * uu * t * curve.control1.y;
y += 3 * u * tt * curve.control2.y;
y += ttt * curve.endPoint.y;
width = startWidth + ttt * widthDelta;
this._drawPoint(x, y, width);
}
ctx.closePath();
ctx.fill();
};
SignaturePad.prototype._strokeWidth = function (velocity) {
return Math.max(this.maxWidth / (velocity + 1), this.minWidth);
};
var Point = function (x, y, time) {
this.x = x;
this.y = y;
this.time = time || new Date().getTime();
};
Point.prototype.velocityFrom = function (start) {
return (this.time !== start.time) ? this.distanceTo(start) / (this.time - start.time) : 1;
};
Point.prototype.distanceTo = function (start) {
return Math.sqrt(Math.pow(this.x - start.x, 2) + Math.pow(this.y - start.y, 2));
};
var Bezier = function (startPoint, control1, control2, endPoint) {
this.startPoint = startPoint;
this.control1 = control1;
this.control2 = control2;
this.endPoint = endPoint;
};
// Returns approximated length.
Bezier.prototype.length = function () {
var steps = 10,
length = 0,
i, t, cx, cy, px, py, xdiff, ydiff;
for (i = 0; i <= steps; i++) {
t = i / steps;
cx = this._point(t, this.startPoint.x, this.control1.x, this.control2.x, this.endPoint.x);
cy = this._point(t, this.startPoint.y, this.control1.y, this.control2.y, this.endPoint.y);
if (i > 0) {
xdiff = cx - px;
ydiff = cy - py;
length += Math.sqrt(xdiff * xdiff + ydiff * ydiff);
}
px = cx;
py = cy;
}
return length;
};
Bezier.prototype._point = function (t, start, c1, c2, end) {
return start * (1.0 - t) * (1.0 - t) * (1.0 - t)
+ 3.0 * c1 * (1.0 - t) * (1.0 - t) * t
+ 3.0 * c2 * (1.0 - t) * t * t
+ end * t * t * t;
};
return SignaturePad;
})(document);
return SignaturePad;
}));

5
public/assets/js/signature_pad.min.js vendored Executable file

File diff suppressed because one or more lines are too long

View file

@ -104,6 +104,22 @@ return array(
'width_w' => 'w',
'height_h' => 'h',
'text_pt' => 'pt',
'two_factor' => 'Two Factor Authentication',
'two_factor_secret' => 'Two-Factor Code',
'two_factor_enrollment' => 'Two-Factor Enrollment',
'two_factor_enabled_text' => 'Enable Two Factor',
'two_factor_reset' => 'Reset Two-Factor Secret',
'two_factor_reset_help' => 'This will force the user to enroll their device with Google Authenticator again. This can be useful if their currently enrolled device is lost or stolen. ',
'two_factor_reset_success' => 'Two factor device successfully reset',
'two_factor_reset_error' => 'Two factor device reset failed',
'two_factor_enabled_warning' => 'Enabling two-factor if it is not currently enabled will immediately force you to authenticate with a Google Auth enrolled device. You will have the ability to enroll your device if one is not currently enrolled.',
'two_factor_enabled_help' => 'This will turn on two-factor authentication using Google Authenticator.',
'two_factor_optional' => 'Optional (Users can enable or disable)',
'two_factor_required' => 'Required for all users',
'two_factor_disabled' => 'Disabled',
'two_factor_enter_code' => 'Enter Two-Factor Code',
'two_factor_config_complete' => 'Submit Code',
'two_factor_enrollment_text' => "Two factor authentication is required, however your device has not been enrolled yet. Open your Google Authenticator app and scan the QR code below to enroll your device. Once you've enrolled your device, enter the code below",
'left' => 'left',
'right' => 'right',
'top' => 'top',

View file

@ -93,7 +93,7 @@
'list_all' => 'عرض الكل',
'loading' => 'Loading',
'lock_passwords' => 'This field cannot be edited in this installation.',
'feature_disabled' => 'This feature has been disabled for this installation.',
'feature_disabled' => 'This feature has been disabled for the demo installation.',
'location' => 'الموقع',
'locations' => 'المواقع',
'logout' => 'تسجيل خروج',
@ -151,6 +151,7 @@
'status_labels' => 'بطاقات الحالة',
'status' => 'الحالة',
'suppliers' => 'الموردون',
'submit' => 'Submit',
'total_assets' => 'إجمالي الأصول',
'total_licenses' => 'إجمالي الرخص',
'total_accessories' => 'total accessories',

View file

@ -104,6 +104,22 @@ return array(
'width_w' => 'w',
'height_h' => 'h',
'text_pt' => 'pt',
'two_factor' => 'Two Factor Authentication',
'two_factor_secret' => 'Two-Factor Code',
'two_factor_enrollment' => 'Two-Factor Enrollment',
'two_factor_enabled_text' => 'Enable Two Factor',
'two_factor_reset' => 'Reset Two-Factor Secret',
'two_factor_reset_help' => 'This will force the user to enroll their device with Google Authenticator again. This can be useful if their currently enrolled device is lost or stolen. ',
'two_factor_reset_success' => 'Two factor device successfully reset',
'two_factor_reset_error' => 'Two factor device reset failed',
'two_factor_enabled_warning' => 'Enabling two-factor if it is not currently enabled will immediately force you to authenticate with a Google Auth enrolled device. You will have the ability to enroll your device if one is not currently enrolled.',
'two_factor_enabled_help' => 'This will turn on two-factor authentication using Google Authenticator.',
'two_factor_optional' => 'Optional (Users can enable or disable)',
'two_factor_required' => 'Required for all users',
'two_factor_disabled' => 'Disabled',
'two_factor_enter_code' => 'Enter Two-Factor Code',
'two_factor_config_complete' => 'Submit Code',
'two_factor_enrollment_text' => "Two factor authentication is required, however your device has not been enrolled yet. Open your Google Authenticator app and scan the QR code below to enroll your device. Once you've enrolled your device, enter the code below",
'left' => 'left',
'right' => 'right',
'top' => 'top',

View file

@ -93,7 +93,7 @@
'list_all' => 'Преглед на всички',
'loading' => 'Зареждане',
'lock_passwords' => 'Полето не може да бъде редактирано в тази конфигурация.',
'feature_disabled' => 'Функционалността е неактивна в тази конфигурация.',
'feature_disabled' => 'This feature has been disabled for the demo installation.',
'location' => 'Местоположение',
'locations' => 'Местоположения',
'logout' => 'Изход',
@ -151,6 +151,7 @@
'status_labels' => 'Статус етикети',
'status' => 'Статус',
'suppliers' => 'Доставчици',
'submit' => 'Submit',
'total_assets' => 'общо активи',
'total_licenses' => 'общо лицензи',
'total_accessories' => 'total accessories',

View file

@ -104,6 +104,22 @@ return array(
'width_w' => 'w',
'height_h' => 'h',
'text_pt' => 'pt',
'two_factor' => 'Two Factor Authentication',
'two_factor_secret' => 'Two-Factor Code',
'two_factor_enrollment' => 'Two-Factor Enrollment',
'two_factor_enabled_text' => 'Enable Two Factor',
'two_factor_reset' => 'Reset Two-Factor Secret',
'two_factor_reset_help' => 'This will force the user to enroll their device with Google Authenticator again. This can be useful if their currently enrolled device is lost or stolen. ',
'two_factor_reset_success' => 'Two factor device successfully reset',
'two_factor_reset_error' => 'Two factor device reset failed',
'two_factor_enabled_warning' => 'Enabling two-factor if it is not currently enabled will immediately force you to authenticate with a Google Auth enrolled device. You will have the ability to enroll your device if one is not currently enrolled.',
'two_factor_enabled_help' => 'This will turn on two-factor authentication using Google Authenticator.',
'two_factor_optional' => 'Optional (Users can enable or disable)',
'two_factor_required' => 'Required for all users',
'two_factor_disabled' => 'Disabled',
'two_factor_enter_code' => 'Enter Two-Factor Code',
'two_factor_config_complete' => 'Submit Code',
'two_factor_enrollment_text' => "Two factor authentication is required, however your device has not been enrolled yet. Open your Google Authenticator app and scan the QR code below to enroll your device. Once you've enrolled your device, enter the code below",
'left' => 'left',
'right' => 'right',
'top' => 'top',

View file

@ -93,7 +93,7 @@
'list_all' => 'Vypsat vše',
'loading' => 'Nahrávání',
'lock_passwords' => 'This field cannot be edited in this installation.',
'feature_disabled' => 'This feature has been disabled for this installation.',
'feature_disabled' => 'This feature has been disabled for the demo installation.',
'location' => 'Lokalita',
'locations' => 'Umístění',
'logout' => 'Odhlásit',
@ -151,6 +151,7 @@
'status_labels' => 'Označení stavu',
'status' => 'Stav',
'suppliers' => 'Dodavatelé',
'submit' => 'Submit',
'total_assets' => 'celkem zařízení',
'total_licenses' => 'celkem licencí',
'total_accessories' => 'total accessories',

View file

@ -104,6 +104,22 @@ return array(
'width_w' => 'w',
'height_h' => 'h',
'text_pt' => 'pt',
'two_factor' => 'Two Factor Authentication',
'two_factor_secret' => 'Two-Factor Code',
'two_factor_enrollment' => 'Two-Factor Enrollment',
'two_factor_enabled_text' => 'Enable Two Factor',
'two_factor_reset' => 'Reset Two-Factor Secret',
'two_factor_reset_help' => 'This will force the user to enroll their device with Google Authenticator again. This can be useful if their currently enrolled device is lost or stolen. ',
'two_factor_reset_success' => 'Two factor device successfully reset',
'two_factor_reset_error' => 'Two factor device reset failed',
'two_factor_enabled_warning' => 'Enabling two-factor if it is not currently enabled will immediately force you to authenticate with a Google Auth enrolled device. You will have the ability to enroll your device if one is not currently enrolled.',
'two_factor_enabled_help' => 'This will turn on two-factor authentication using Google Authenticator.',
'two_factor_optional' => 'Optional (Users can enable or disable)',
'two_factor_required' => 'Required for all users',
'two_factor_disabled' => 'Disabled',
'two_factor_enter_code' => 'Enter Two-Factor Code',
'two_factor_config_complete' => 'Submit Code',
'two_factor_enrollment_text' => "Two factor authentication is required, however your device has not been enrolled yet. Open your Google Authenticator app and scan the QR code below to enroll your device. Once you've enrolled your device, enter the code below",
'left' => 'left',
'right' => 'right',
'top' => 'top',

View file

@ -93,7 +93,7 @@
'list_all' => 'Vis alle',
'loading' => 'Indlæser',
'lock_passwords' => 'This field cannot be edited in this installation.',
'feature_disabled' => 'This feature has been disabled for this installation.',
'feature_disabled' => 'This feature has been disabled for the demo installation.',
'location' => 'Lokation',
'locations' => 'Lokationer',
'logout' => 'Log ud',
@ -151,6 +151,7 @@
'status_labels' => 'Status labels',
'status' => 'Status',
'suppliers' => 'Leverandører',
'submit' => 'Submit',
'total_assets' => 'totale aktiver',
'total_licenses' => 'totale licenser',
'total_accessories' => 'total accessories',

View file

@ -104,6 +104,22 @@ return array(
'width_w' => 'b',
'height_h' => 'h',
'text_pt' => 'pt',
'two_factor' => 'Two Factor Authentication',
'two_factor_secret' => 'Two-Factor Code',
'two_factor_enrollment' => 'Two-Factor Enrollment',
'two_factor_enabled_text' => 'Enable Two Factor',
'two_factor_reset' => 'Reset Two-Factor Secret',
'two_factor_reset_help' => 'This will force the user to enroll their device with Google Authenticator again. This can be useful if their currently enrolled device is lost or stolen. ',
'two_factor_reset_success' => 'Two factor device successfully reset',
'two_factor_reset_error' => 'Two factor device reset failed',
'two_factor_enabled_warning' => 'Enabling two-factor if it is not currently enabled will immediately force you to authenticate with a Google Auth enrolled device. You will have the ability to enroll your device if one is not currently enrolled.',
'two_factor_enabled_help' => 'This will turn on two-factor authentication using Google Authenticator.',
'two_factor_optional' => 'Optional (Users can enable or disable)',
'two_factor_required' => 'Required for all users',
'two_factor_disabled' => 'Disabled',
'two_factor_enter_code' => 'Enter Two-Factor Code',
'two_factor_config_complete' => 'Submit Code',
'two_factor_enrollment_text' => "Two factor authentication is required, however your device has not been enrolled yet. Open your Google Authenticator app and scan the QR code below to enroll your device. Once you've enrolled your device, enter the code below",
'left' => 'links',
'right' => 'rechts',
'top' => 'Oben',

View file

@ -93,7 +93,7 @@
'list_all' => 'Alle auflisten',
'loading' => 'Am laden',
'lock_passwords' => 'Dieses Feld kann in dieser Installation nicht bearbeitet werden.',
'feature_disabled' => 'Die Funktion wurde in dieser Installation deaktiviert.',
'feature_disabled' => 'This feature has been disabled for the demo installation.',
'location' => 'Standort',
'locations' => 'Standorte',
'logout' => 'Abmelden',
@ -151,6 +151,7 @@
'status_labels' => 'Statusbezeichnungen',
'status' => 'Status',
'suppliers' => 'Lieferanten',
'submit' => 'Submit',
'total_assets' => 'Gesamte Assets',
'total_licenses' => 'Lizenzen insgesamt',
'total_accessories' => 'gesamtes Zubehör',

View file

@ -104,6 +104,22 @@ return array(
'width_w' => 'w',
'height_h' => 'h',
'text_pt' => 'pt',
'two_factor' => 'Two Factor Authentication',
'two_factor_secret' => 'Two-Factor Code',
'two_factor_enrollment' => 'Two-Factor Enrollment',
'two_factor_enabled_text' => 'Enable Two Factor',
'two_factor_reset' => 'Reset Two-Factor Secret',
'two_factor_reset_help' => 'This will force the user to enroll their device with Google Authenticator again. This can be useful if their currently enrolled device is lost or stolen. ',
'two_factor_reset_success' => 'Two factor device successfully reset',
'two_factor_reset_error' => 'Two factor device reset failed',
'two_factor_enabled_warning' => 'Enabling two-factor if it is not currently enabled will immediately force you to authenticate with a Google Auth enrolled device. You will have the ability to enroll your device if one is not currently enrolled.',
'two_factor_enabled_help' => 'This will turn on two-factor authentication using Google Authenticator.',
'two_factor_optional' => 'Optional (Users can enable or disable)',
'two_factor_required' => 'Required for all users',
'two_factor_disabled' => 'Disabled',
'two_factor_enter_code' => 'Enter Two-Factor Code',
'two_factor_config_complete' => 'Submit Code',
'two_factor_enrollment_text' => "Two factor authentication is required, however your device has not been enrolled yet. Open your Google Authenticator app and scan the QR code below to enroll your device. Once you've enrolled your device, enter the code below",
'left' => 'left',
'right' => 'right',
'top' => 'top',

View file

@ -93,7 +93,7 @@
'list_all' => 'List All',
'loading' => 'Loading',
'lock_passwords' => 'This field cannot be edited in this installation.',
'feature_disabled' => 'This feature has been disabled for this installation.',
'feature_disabled' => 'This feature has been disabled for the demo installation.',
'location' => 'Location',
'locations' => 'Locations',
'logout' => 'Logout',
@ -151,6 +151,7 @@
'status_labels' => 'Status Labels',
'status' => 'Status',
'suppliers' => 'Suppliers',
'submit' => 'Submit',
'total_assets' => 'total assets',
'total_licenses' => 'total licenses',
'total_accessories' => 'total accessories',

View file

@ -104,6 +104,22 @@ return array(
'width_w' => 'w',
'height_h' => 'h',
'text_pt' => 'pt',
'two_factor' => 'Two Factor Authentication',
'two_factor_secret' => 'Two-Factor Code',
'two_factor_enrollment' => 'Two-Factor Enrollment',
'two_factor_enabled_text' => 'Enable Two Factor',
'two_factor_reset' => 'Reset Two-Factor Secret',
'two_factor_reset_help' => 'This will force the user to enroll their device with Google Authenticator again. This can be useful if their currently enrolled device is lost or stolen. ',
'two_factor_reset_success' => 'Two factor device successfully reset',
'two_factor_reset_error' => 'Two factor device reset failed',
'two_factor_enabled_warning' => 'Enabling two-factor if it is not currently enabled will immediately force you to authenticate with a Google Auth enrolled device. You will have the ability to enroll your device if one is not currently enrolled.',
'two_factor_enabled_help' => 'This will turn on two-factor authentication using Google Authenticator.',
'two_factor_optional' => 'Optional (Users can enable or disable)',
'two_factor_required' => 'Required for all users',
'two_factor_disabled' => 'Disabled',
'two_factor_enter_code' => 'Enter Two-Factor Code',
'two_factor_config_complete' => 'Submit Code',
'two_factor_enrollment_text' => "Two factor authentication is required, however your device has not been enrolled yet. Open your Google Authenticator app and scan the QR code below to enroll your device. Once you've enrolled your device, enter the code below",
'left' => 'left',
'right' => 'right',
'top' => 'top',

View file

@ -93,7 +93,7 @@
'list_all' => 'List All',
'loading' => 'Loading',
'lock_passwords' => 'This field cannot be edited in this installation.',
'feature_disabled' => 'This feature has been disabled for this installation.',
'feature_disabled' => 'This feature has been disabled for the demo installation.',
'location' => 'Location',
'locations' => 'Locations',
'logout' => 'Logout',
@ -151,6 +151,7 @@
'status_labels' => 'Status Labels',
'status' => 'Status',
'suppliers' => 'Suppliers',
'submit' => 'Submit',
'total_assets' => 'total assets',
'total_licenses' => 'total licenses',
'total_accessories' => 'total accessories',

View file

@ -104,6 +104,22 @@ return array(
'width_w' => 'w',
'height_h' => 'h',
'text_pt' => 'pt',
'two_factor' => 'Two Factor Authentication',
'two_factor_secret' => 'Two-Factor Code',
'two_factor_enrollment' => 'Two-Factor Enrollment',
'two_factor_enabled_text' => 'Enable Two Factor',
'two_factor_reset' => 'Reset Two-Factor Secret',
'two_factor_reset_help' => 'This will force the user to enroll their device with Google Authenticator again. This can be useful if their currently enrolled device is lost or stolen. ',
'two_factor_reset_success' => 'Two factor device successfully reset',
'two_factor_reset_error' => 'Two factor device reset failed',
'two_factor_enabled_warning' => 'Enabling two-factor if it is not currently enabled will immediately force you to authenticate with a Google Auth enrolled device. You will have the ability to enroll your device if one is not currently enrolled.',
'two_factor_enabled_help' => 'This will turn on two-factor authentication using Google Authenticator.',
'two_factor_optional' => 'Optional (Users can enable or disable)',
'two_factor_required' => 'Required for all users',
'two_factor_disabled' => 'Disabled',
'two_factor_enter_code' => 'Enter Two-Factor Code',
'two_factor_config_complete' => 'Submit Code',
'two_factor_enrollment_text' => "Two factor authentication is required, however your device has not been enrolled yet. Open your Google Authenticator app and scan the QR code below to enroll your device. Once you've enrolled your device, enter the code below",
'left' => 'left',
'right' => 'right',
'top' => 'top',

View file

@ -93,7 +93,7 @@
'list_all' => 'List All',
'loading' => 'Loading',
'lock_passwords' => 'This field cannot be edited in this installation.',
'feature_disabled' => 'This feature has been disabled for this installation.',
'feature_disabled' => 'This feature has been disabled for the demo installation.',
'location' => 'Location',
'locations' => 'Locations',
'logout' => 'Logout',
@ -151,6 +151,7 @@
'status_labels' => 'Status Labels',
'status' => 'Status',
'suppliers' => 'Suppliers',
'submit' => 'Submit',
'total_assets' => 'total assets',
'total_licenses' => 'total licenses',
'total_accessories' => 'total accessories',

View file

@ -104,6 +104,25 @@ return array(
'width_w' => 'w',
'height_h' => 'h',
'text_pt' => 'pt',
'two_factor' => 'Two Factor Authentication',
'two_factor_secret' => 'Two-Factor Code',
'two_factor_enrollment' => 'Two-Factor Enrollment',
'two_factor_enabled_text' => 'Enable Two Factor',
'two_factor_reset' => 'Reset Two-Factor Secret',
'two_factor_reset_help' => 'This will force the user to enroll their device with Google Authenticator again. This can be useful if their currently enrolled device is lost or stolen. ',
'two_factor_reset_success' => 'Two factor device successfully reset',
'two_factor_reset_error' => 'Two factor device reset failed',
'two_factor_enabled_warning' => 'Enabling two-factor if it is not currently enabled will immediately force you to authenticate with a Google Auth enrolled device. You will have the ability to enroll your device if one is not currently enrolled.',
'two_factor_enabled_help' => 'This will turn on two-factor authentication using Google Authenticator.',
'two_factor_optional' => 'Selective (Users can enable or disable if permitted)',
'two_factor_required' => 'Required for all users',
'two_factor_disabled' => 'Disabled',
'two_factor_enter_code' => 'Enter Two-Factor Code',
'two_factor_config_complete' => 'Submit Code',
'two_factor_enabled_edit_not_allowed' => 'Your administrator does not permit you to edit this setting.',
'two_factor_enrollment_text' => "Two factor authentication is required, however your device has not been enrolled yet. Open your Google Authenticator app and scan the QR code below to enroll your device. Once you've enrolled your device, enter the code below",
'require_accept_signature' => 'Require Signature',
'require_accept_signature_help_text' => 'Enabling this feature will require users to physically sign off on accepting an asset.',
'left' => 'left',
'right' => 'right',
'top' => 'top',

View file

@ -15,4 +15,7 @@ return array(
'software_user' => 'Software Checked out to :name',
'view_user' => 'View User :name',
'usercsv' => 'CSV file',
'two_factor_admin_optin_help' => 'Your current admin settings allow selective enforcement of two-factor authentication. ',
'two_factor_enrolled' => '2FA Device Enrolled ',
'two_factor_active' => '2FA Active ',
);

View file

@ -93,7 +93,7 @@
'list_all' => 'List All',
'loading' => 'Loading',
'lock_passwords' => 'This field cannot be edited in this installation.',
'feature_disabled' => 'This feature has been disabled for this installation.',
'feature_disabled' => 'This feature has been disabled for the demo installation.',
'location' => 'Location',
'locations' => 'Locations',
'logout' => 'Logout',
@ -145,12 +145,14 @@
'select_asset' => 'Select Asset',
'settings' => 'Settings',
'sign_in' => 'Sign in',
'signature' => 'Signature',
'some_features_disabled' => 'DEMO MODE: Some features are disabled for this installation.',
'site_name' => 'Site Name',
'state' => 'State',
'status_labels' => 'Status Labels',
'status' => 'Status',
'suppliers' => 'Suppliers',
'submit' => 'Submit',
'total_assets' => 'total assets',
'total_licenses' => 'total licenses',
'total_accessories' => 'total accessories',

View file

@ -104,6 +104,22 @@ return array(
'width_w' => 'w',
'height_h' => 'h',
'text_pt' => 'pt',
'two_factor' => 'Two Factor Authentication',
'two_factor_secret' => 'Two-Factor Code',
'two_factor_enrollment' => 'Two-Factor Enrollment',
'two_factor_enabled_text' => 'Enable Two Factor',
'two_factor_reset' => 'Reset Two-Factor Secret',
'two_factor_reset_help' => 'This will force the user to enroll their device with Google Authenticator again. This can be useful if their currently enrolled device is lost or stolen. ',
'two_factor_reset_success' => 'Two factor device successfully reset',
'two_factor_reset_error' => 'Two factor device reset failed',
'two_factor_enabled_warning' => 'Enabling two-factor if it is not currently enabled will immediately force you to authenticate with a Google Auth enrolled device. You will have the ability to enroll your device if one is not currently enrolled.',
'two_factor_enabled_help' => 'This will turn on two-factor authentication using Google Authenticator.',
'two_factor_optional' => 'Optional (Users can enable or disable)',
'two_factor_required' => 'Required for all users',
'two_factor_disabled' => 'Disabled',
'two_factor_enter_code' => 'Enter Two-Factor Code',
'two_factor_config_complete' => 'Submit Code',
'two_factor_enrollment_text' => "Two factor authentication is required, however your device has not been enrolled yet. Open your Google Authenticator app and scan the QR code below to enroll your device. Once you've enrolled your device, enter the code below",
'left' => 'left',
'right' => 'right',
'top' => 'top',

View file

@ -93,7 +93,7 @@
'list_all' => 'List All',
'loading' => 'Loading',
'lock_passwords' => 'This field cannot be edited in this installation.',
'feature_disabled' => 'This feature has been disabled for this installation.',
'feature_disabled' => 'This feature has been disabled for the demo installation.',
'location' => 'Location',
'locations' => 'Locations',
'logout' => 'Logout',
@ -151,6 +151,7 @@
'status_labels' => 'Status Labels',
'status' => 'Status',
'suppliers' => 'Suppliers',
'submit' => 'Submit',
'total_assets' => 'total assets',
'total_licenses' => 'total licenses',
'total_accessories' => 'total accessories',

View file

@ -104,6 +104,22 @@ return array(
'width_w' => 'an',
'height_h' => 'al',
'text_pt' => 'pt',
'two_factor' => 'Two Factor Authentication',
'two_factor_secret' => 'Two-Factor Code',
'two_factor_enrollment' => 'Two-Factor Enrollment',
'two_factor_enabled_text' => 'Enable Two Factor',
'two_factor_reset' => 'Reset Two-Factor Secret',
'two_factor_reset_help' => 'This will force the user to enroll their device with Google Authenticator again. This can be useful if their currently enrolled device is lost or stolen. ',
'two_factor_reset_success' => 'Two factor device successfully reset',
'two_factor_reset_error' => 'Two factor device reset failed',
'two_factor_enabled_warning' => 'Enabling two-factor if it is not currently enabled will immediately force you to authenticate with a Google Auth enrolled device. You will have the ability to enroll your device if one is not currently enrolled.',
'two_factor_enabled_help' => 'This will turn on two-factor authentication using Google Authenticator.',
'two_factor_optional' => 'Optional (Users can enable or disable)',
'two_factor_required' => 'Required for all users',
'two_factor_disabled' => 'Disabled',
'two_factor_enter_code' => 'Enter Two-Factor Code',
'two_factor_config_complete' => 'Submit Code',
'two_factor_enrollment_text' => "Two factor authentication is required, however your device has not been enrolled yet. Open your Google Authenticator app and scan the QR code below to enroll your device. Once you've enrolled your device, enter the code below",
'left' => 'izquierda',
'right' => 'derecha',
'top' => 'arriba',

View file

@ -93,7 +93,7 @@
'list_all' => 'Listar Todo',
'loading' => 'Cargando',
'lock_passwords' => 'Este campo no puede ser editado en ésta instalación.',
'feature_disabled' => 'Esta funcionalidad ha sido deshabilitada para esta instalación.',
'feature_disabled' => 'This feature has been disabled for the demo installation.',
'location' => 'Localización',
'locations' => 'Localizaciones',
'logout' => 'Desconexión',
@ -151,6 +151,7 @@
'status_labels' => 'Etiquetas Estados',
'status' => 'Estados',
'suppliers' => 'Proveedores',
'submit' => 'Submit',
'total_assets' => 'Equipos',
'total_licenses' => 'licencias totales',
'total_accessories' => 'total accessories',

View file

@ -105,6 +105,22 @@ return array(
'width_w' => 'عرض',
'height_h' => 'ارتفاع',
'text_pt' => 'بالای صفحه',
'two_factor' => 'Two Factor Authentication',
'two_factor_secret' => 'Two-Factor Code',
'two_factor_enrollment' => 'Two-Factor Enrollment',
'two_factor_enabled_text' => 'Enable Two Factor',
'two_factor_reset' => 'Reset Two-Factor Secret',
'two_factor_reset_help' => 'This will force the user to enroll their device with Google Authenticator again. This can be useful if their currently enrolled device is lost or stolen. ',
'two_factor_reset_success' => 'Two factor device successfully reset',
'two_factor_reset_error' => 'Two factor device reset failed',
'two_factor_enabled_warning' => 'Enabling two-factor if it is not currently enabled will immediately force you to authenticate with a Google Auth enrolled device. You will have the ability to enroll your device if one is not currently enrolled.',
'two_factor_enabled_help' => 'This will turn on two-factor authentication using Google Authenticator.',
'two_factor_optional' => 'Optional (Users can enable or disable)',
'two_factor_required' => 'Required for all users',
'two_factor_disabled' => 'Disabled',
'two_factor_enter_code' => 'Enter Two-Factor Code',
'two_factor_config_complete' => 'Submit Code',
'two_factor_enrollment_text' => "Two factor authentication is required, however your device has not been enrolled yet. Open your Google Authenticator app and scan the QR code below to enroll your device. Once you've enrolled your device, enter the code below",
'left' => 'چپ',
'right' => 'راست',
'top' => 'بالا',

View file

@ -97,7 +97,7 @@
'loading' => 'بارگزاری',
'lock_passwords' => 'در این زمینه می توانید نصب و راه اندازی را ویرایش کنید.
',
'feature_disabled' => 'این قابلیت برای این نصب و راه اندازی غیر فعال است.',
'feature_disabled' => 'This feature has been disabled for the demo installation.',
'location' => 'مکان',
'locations' => 'مکانها',
'logout' => 'خروج',
@ -155,6 +155,7 @@
'status_labels' => 'برچسب های وضعیت',
'status' => 'وضعیت',
'suppliers' => 'تامین کننده',
'submit' => 'Submit',
'total_assets' => 'کل دارایی',
'total_licenses' => 'کل مجوزهای',
'total_accessories' => 'total accessories',

View file

@ -104,6 +104,22 @@ return array(
'width_w' => 'w',
'height_h' => 'h',
'text_pt' => 'pt',
'two_factor' => 'Two Factor Authentication',
'two_factor_secret' => 'Two-Factor Code',
'two_factor_enrollment' => 'Two-Factor Enrollment',
'two_factor_enabled_text' => 'Enable Two Factor',
'two_factor_reset' => 'Reset Two-Factor Secret',
'two_factor_reset_help' => 'This will force the user to enroll their device with Google Authenticator again. This can be useful if their currently enrolled device is lost or stolen. ',
'two_factor_reset_success' => 'Two factor device successfully reset',
'two_factor_reset_error' => 'Two factor device reset failed',
'two_factor_enabled_warning' => 'Enabling two-factor if it is not currently enabled will immediately force you to authenticate with a Google Auth enrolled device. You will have the ability to enroll your device if one is not currently enrolled.',
'two_factor_enabled_help' => 'This will turn on two-factor authentication using Google Authenticator.',
'two_factor_optional' => 'Optional (Users can enable or disable)',
'two_factor_required' => 'Required for all users',
'two_factor_disabled' => 'Disabled',
'two_factor_enter_code' => 'Enter Two-Factor Code',
'two_factor_config_complete' => 'Submit Code',
'two_factor_enrollment_text' => "Two factor authentication is required, however your device has not been enrolled yet. Open your Google Authenticator app and scan the QR code below to enroll your device. Once you've enrolled your device, enter the code below",
'left' => 'left',
'right' => 'right',
'top' => 'top',

View file

@ -93,7 +93,7 @@
'list_all' => 'Listaa Kaikki',
'loading' => 'Ladataan',
'lock_passwords' => 'This field cannot be edited in this installation.',
'feature_disabled' => 'This feature has been disabled for this installation.',
'feature_disabled' => 'This feature has been disabled for the demo installation.',
'location' => 'Sijainti',
'locations' => 'Sijainnit',
'logout' => 'Kirjaudu Ulos',
@ -151,6 +151,7 @@
'status_labels' => 'Tilamerkinnät',
'status' => 'Tila',
'suppliers' => 'Toimittajat',
'submit' => 'Submit',
'total_assets' => 'laitteita yhteensä',
'total_licenses' => 'lisenssejä yhteensä',
'total_accessories' => 'total accessories',

View file

@ -104,6 +104,22 @@ return array(
'width_w' => 'l',
'height_h' => 'h',
'text_pt' => 'pt',
'two_factor' => 'Two Factor Authentication',
'two_factor_secret' => 'Two-Factor Code',
'two_factor_enrollment' => 'Two-Factor Enrollment',
'two_factor_enabled_text' => 'Enable Two Factor',
'two_factor_reset' => 'Reset Two-Factor Secret',
'two_factor_reset_help' => 'This will force the user to enroll their device with Google Authenticator again. This can be useful if their currently enrolled device is lost or stolen. ',
'two_factor_reset_success' => 'Two factor device successfully reset',
'two_factor_reset_error' => 'Two factor device reset failed',
'two_factor_enabled_warning' => 'Enabling two-factor if it is not currently enabled will immediately force you to authenticate with a Google Auth enrolled device. You will have the ability to enroll your device if one is not currently enrolled.',
'two_factor_enabled_help' => 'This will turn on two-factor authentication using Google Authenticator.',
'two_factor_optional' => 'Optional (Users can enable or disable)',
'two_factor_required' => 'Required for all users',
'two_factor_disabled' => 'Disabled',
'two_factor_enter_code' => 'Enter Two-Factor Code',
'two_factor_config_complete' => 'Submit Code',
'two_factor_enrollment_text' => "Two factor authentication is required, however your device has not been enrolled yet. Open your Google Authenticator app and scan the QR code below to enroll your device. Once you've enrolled your device, enter the code below",
'left' => 'gauche',
'right' => 'droite',
'top' => 'haut',

View file

@ -93,7 +93,7 @@
'list_all' => 'Lister tout',
'loading' => 'Chargement',
'lock_passwords' => 'Ce champ ne peut pas être modifié dans cette installation.',
'feature_disabled' => 'Cette option n\'est pas disponible pour cette installation.',
'feature_disabled' => 'This feature has been disabled for the demo installation.',
'location' => 'Lieu',
'locations' => 'Lieux',
'logout' => 'Se déconnecter',
@ -151,6 +151,7 @@
'status_labels' => 'Étiquette de statut',
'status' => 'Statut',
'suppliers' => 'Fournisseurs',
'submit' => 'Submit',
'total_assets' => 'actifs au total',
'total_licenses' => 'licences au total',
'total_accessories' => 'accessoires au total',

View file

@ -104,6 +104,22 @@ return array(
'width_w' => 'w',
'height_h' => 'h',
'text_pt' => 'pt',
'two_factor' => 'Two Factor Authentication',
'two_factor_secret' => 'Two-Factor Code',
'two_factor_enrollment' => 'Two-Factor Enrollment',
'two_factor_enabled_text' => 'Enable Two Factor',
'two_factor_reset' => 'Reset Two-Factor Secret',
'two_factor_reset_help' => 'This will force the user to enroll their device with Google Authenticator again. This can be useful if their currently enrolled device is lost or stolen. ',
'two_factor_reset_success' => 'Two factor device successfully reset',
'two_factor_reset_error' => 'Two factor device reset failed',
'two_factor_enabled_warning' => 'Enabling two-factor if it is not currently enabled will immediately force you to authenticate with a Google Auth enrolled device. You will have the ability to enroll your device if one is not currently enrolled.',
'two_factor_enabled_help' => 'This will turn on two-factor authentication using Google Authenticator.',
'two_factor_optional' => 'Optional (Users can enable or disable)',
'two_factor_required' => 'Required for all users',
'two_factor_disabled' => 'Disabled',
'two_factor_enter_code' => 'Enter Two-Factor Code',
'two_factor_config_complete' => 'Submit Code',
'two_factor_enrollment_text' => "Two factor authentication is required, however your device has not been enrolled yet. Open your Google Authenticator app and scan the QR code below to enroll your device. Once you've enrolled your device, enter the code below",
'left' => 'left',
'right' => 'right',
'top' => 'top',

View file

@ -93,7 +93,7 @@
'list_all' => 'List All',
'loading' => 'Loading',
'lock_passwords' => 'This field cannot be edited in this installation.',
'feature_disabled' => 'This feature has been disabled for this installation.',
'feature_disabled' => 'This feature has been disabled for the demo installation.',
'location' => 'Location',
'locations' => 'Locations',
'logout' => 'Logout',
@ -151,6 +151,7 @@
'status_labels' => 'Status Labels',
'status' => 'Status',
'suppliers' => 'Suppliers',
'submit' => 'Submit',
'total_assets' => 'total assets',
'total_licenses' => 'total licenses',
'total_accessories' => 'total accessories',

View file

@ -104,6 +104,22 @@ return array(
'width_w' => 'w',
'height_h' => 'h',
'text_pt' => 'pt',
'two_factor' => 'Two Factor Authentication',
'two_factor_secret' => 'Two-Factor Code',
'two_factor_enrollment' => 'Two-Factor Enrollment',
'two_factor_enabled_text' => 'Enable Two Factor',
'two_factor_reset' => 'Reset Two-Factor Secret',
'two_factor_reset_help' => 'This will force the user to enroll their device with Google Authenticator again. This can be useful if their currently enrolled device is lost or stolen. ',
'two_factor_reset_success' => 'Two factor device successfully reset',
'two_factor_reset_error' => 'Two factor device reset failed',
'two_factor_enabled_warning' => 'Enabling two-factor if it is not currently enabled will immediately force you to authenticate with a Google Auth enrolled device. You will have the ability to enroll your device if one is not currently enrolled.',
'two_factor_enabled_help' => 'This will turn on two-factor authentication using Google Authenticator.',
'two_factor_optional' => 'Optional (Users can enable or disable)',
'two_factor_required' => 'Required for all users',
'two_factor_disabled' => 'Disabled',
'two_factor_enter_code' => 'Enter Two-Factor Code',
'two_factor_config_complete' => 'Submit Code',
'two_factor_enrollment_text' => "Two factor authentication is required, however your device has not been enrolled yet. Open your Google Authenticator app and scan the QR code below to enroll your device. Once you've enrolled your device, enter the code below",
'left' => 'left',
'right' => 'right',
'top' => 'top',

View file

@ -93,7 +93,7 @@
'list_all' => 'List All',
'loading' => 'Loading',
'lock_passwords' => 'This field cannot be edited in this installation.',
'feature_disabled' => 'This feature has been disabled for this installation.',
'feature_disabled' => 'This feature has been disabled for the demo installation.',
'location' => 'Location',
'locations' => 'Locations',
'logout' => 'Logout',
@ -151,6 +151,7 @@
'status_labels' => 'Status Labels',
'status' => 'Status',
'suppliers' => 'Suppliers',
'submit' => 'Submit',
'total_assets' => 'total assets',
'total_licenses' => 'total licenses',
'total_accessories' => 'total accessories',

View file

@ -104,6 +104,22 @@ return array(
'width_w' => 'w',
'height_h' => 'h',
'text_pt' => 'pt',
'two_factor' => 'Two Factor Authentication',
'two_factor_secret' => 'Two-Factor Code',
'two_factor_enrollment' => 'Two-Factor Enrollment',
'two_factor_enabled_text' => 'Enable Two Factor',
'two_factor_reset' => 'Reset Two-Factor Secret',
'two_factor_reset_help' => 'This will force the user to enroll their device with Google Authenticator again. This can be useful if their currently enrolled device is lost or stolen. ',
'two_factor_reset_success' => 'Two factor device successfully reset',
'two_factor_reset_error' => 'Two factor device reset failed',
'two_factor_enabled_warning' => 'Enabling two-factor if it is not currently enabled will immediately force you to authenticate with a Google Auth enrolled device. You will have the ability to enroll your device if one is not currently enrolled.',
'two_factor_enabled_help' => 'This will turn on two-factor authentication using Google Authenticator.',
'two_factor_optional' => 'Optional (Users can enable or disable)',
'two_factor_required' => 'Required for all users',
'two_factor_disabled' => 'Disabled',
'two_factor_enter_code' => 'Enter Two-Factor Code',
'two_factor_config_complete' => 'Submit Code',
'two_factor_enrollment_text' => "Two factor authentication is required, however your device has not been enrolled yet. Open your Google Authenticator app and scan the QR code below to enroll your device. Once you've enrolled your device, enter the code below",
'left' => 'left',
'right' => 'right',
'top' => 'top',

View file

@ -93,7 +93,7 @@
'list_all' => 'Listázd mind',
'loading' => 'Betöltés',
'lock_passwords' => 'A mező nem módosítható ebben a vezióban.',
'feature_disabled' => 'Ez a képesség le van tíltva ebben a verzióban.',
'feature_disabled' => 'This feature has been disabled for the demo installation.',
'location' => 'Helyszín',
'locations' => 'Helyek',
'logout' => 'Kijelentkezés',
@ -151,6 +151,7 @@
'status_labels' => 'Státusz címkék',
'status' => 'Állapot',
'suppliers' => 'Beszállítók',
'submit' => 'Submit',
'total_assets' => 'eszköz összesen',
'total_licenses' => 'licensz összesen',
'total_accessories' => 'total accessories',

View file

@ -104,6 +104,22 @@ return array(
'width_w' => 'l',
'height_h' => 't',
'text_pt' => 'pt',
'two_factor' => 'Two Factor Authentication',
'two_factor_secret' => 'Two-Factor Code',
'two_factor_enrollment' => 'Two-Factor Enrollment',
'two_factor_enabled_text' => 'Enable Two Factor',
'two_factor_reset' => 'Reset Two-Factor Secret',
'two_factor_reset_help' => 'This will force the user to enroll their device with Google Authenticator again. This can be useful if their currently enrolled device is lost or stolen. ',
'two_factor_reset_success' => 'Two factor device successfully reset',
'two_factor_reset_error' => 'Two factor device reset failed',
'two_factor_enabled_warning' => 'Enabling two-factor if it is not currently enabled will immediately force you to authenticate with a Google Auth enrolled device. You will have the ability to enroll your device if one is not currently enrolled.',
'two_factor_enabled_help' => 'This will turn on two-factor authentication using Google Authenticator.',
'two_factor_optional' => 'Optional (Users can enable or disable)',
'two_factor_required' => 'Required for all users',
'two_factor_disabled' => 'Disabled',
'two_factor_enter_code' => 'Enter Two-Factor Code',
'two_factor_config_complete' => 'Submit Code',
'two_factor_enrollment_text' => "Two factor authentication is required, however your device has not been enrolled yet. Open your Google Authenticator app and scan the QR code below to enroll your device. Once you've enrolled your device, enter the code below",
'left' => 'kiri',
'right' => 'kanan',
'top' => 'atas',

View file

@ -93,7 +93,7 @@
'list_all' => 'Tampilkan semua',
'loading' => 'Memuat',
'lock_passwords' => 'Field ini tidak dapat di edit ketika instalasi.',
'feature_disabled' => 'Fitur ini telah di non-aktifkan untuk instalasi ini.',
'feature_disabled' => 'This feature has been disabled for the demo installation.',
'location' => 'Lokasi',
'locations' => 'Lokasi',
'logout' => 'Keluar',
@ -151,6 +151,7 @@
'status_labels' => 'Status label',
'status' => 'Status',
'suppliers' => 'Pemasok',
'submit' => 'Submit',
'total_assets' => 'total aset',
'total_licenses' => 'total lisensi',
'total_accessories' => 'total accessories',

View file

@ -4,7 +4,7 @@ return array(
'deleted' => 'Questo modello è stato eliminato.<a href="/hardware/models/:model_id/restore">Clicca qui per ripristinarlo</a>.',
'restore' => 'Ripristinare il modello',
'requestable' => 'Users may request this model',
'requestable' => 'Gli utenti possono richiedere questo modello',
'show_mac_address' => 'Mostra MAC Address dei beni in questo modello',
'view_deleted' => 'Visualizza Eliminati',
'view_models' => 'Visualizza i modelli',

View file

@ -2,11 +2,11 @@
return array(
'ad' => 'Active Directory',
'ad_domain' => 'Active Directory domain',
'ad_domain' => 'Dominio Active Directory',
'ad_domain_help' => 'This is sometimes the same as your email domain, but not always.',
'is_ad' => 'This is an Active Directory server',
'alert_email' => 'Invia avvisi a',
'alerts_enabled' => 'Alerts Enabled',
'alerts_enabled' => 'Allarmi Attivati',
'alert_interval' => 'Expiring Alerts Threshold (in days)',
'alert_inv_threshold' => 'Inventory Alert Threshold',
'asset_ids' => 'ID modello',
@ -15,13 +15,13 @@ return array(
'auto_incrementing_help' => 'Abilita auto-incremento ID beni prima di impostare questa',
'backups' => 'Backups',
'barcode_settings' => 'Impostazioni codice a barre',
'confirm_purge' => 'Confirm Purge',
'confirm_purge' => 'Conferma Cancellazione',
'confirm_purge_help' => 'Enter the text "DELETE" in the box below to purge your deleted records. This action cannot be undone.',
'custom_css' => 'CSS Personalizzato',
'custom_css_help' => 'Inserisci qualsiasi CSS personalizzato che vuoi utilizzare. Do not include the &lt;style&gt;&lt;/style&gt; tags.',
'default_currency' => 'Valuta predefinita',
'default_eula_text' => 'EULA Predefinita',
'default_language' => 'Default Language',
'default_language' => 'Lingua predefinita',
'default_eula_help_text' => 'È possibile associare EULAs personalizzati a categorie di beni specifici.',
'display_asset_name' => 'Mostra Nome Bene',
'display_checkout_date' => 'Mostra Data Estrazione',
@ -45,13 +45,13 @@ return array(
'ldap_server_cert' => 'Validazione certificato SSL di LDAP',
'ldap_server_cert_ignore' => 'Consenti Certificato SSL non valido',
'ldap_server_cert_help' => 'Seleziona questa casella se stai utilizzando un certificato SSL autofirmato e vuoi accettare un certificato SSL non valido.',
'ldap_tls' => 'Use TLS',
'ldap_tls' => 'Usa TLS',
'ldap_tls_help' => 'This should be checked only if you are running STARTTLS on your LDAP server. ',
'ldap_uname' => 'Nome utente LDAP',
'ldap_pword' => 'Password LDAP',
'ldap_basedn' => 'DN Base',
'ldap_filter' => 'Filtro LDAP',
'ldap_pw_sync' => 'LDAP Password Sync',
'ldap_pw_sync' => 'Sincronizzazione password LDAP',
'ldap_pw_sync_help' => 'Uncheck this box if you do not wish to keep LDAP passwords synced with local passwords. Disabling this means that your users may not be able to login if your LDAP server is unreachable for some reason.',
'ldap_username_field' => 'Campo nome utente',
'ldap_lname_field' => 'Cognome',
@ -88,7 +88,7 @@ return array(
'brand' => 'Personalizzazione',
'about_settings_title' => 'Impostazioni',
'about_settings_text' => 'Queste impostazioni ti permettono di personalizzare alcuni aspetti della tua installazione.',
'labels_per_page' => 'Labels per page',
'labels_per_page' => 'Etichetta per pagina',
'label_dimensions' => 'Label dimensions (inches)',
'page_padding' => 'Page margins (inches)',
'purge' => 'Purge Deleted Records',
@ -104,6 +104,22 @@ return array(
'width_w' => 'w',
'height_h' => 'h',
'text_pt' => 'pt',
'two_factor' => 'Two Factor Authentication',
'two_factor_secret' => 'Two-Factor Code',
'two_factor_enrollment' => 'Two-Factor Enrollment',
'two_factor_enabled_text' => 'Enable Two Factor',
'two_factor_reset' => 'Reset Two-Factor Secret',
'two_factor_reset_help' => 'This will force the user to enroll their device with Google Authenticator again. This can be useful if their currently enrolled device is lost or stolen. ',
'two_factor_reset_success' => 'Two factor device successfully reset',
'two_factor_reset_error' => 'Two factor device reset failed',
'two_factor_enabled_warning' => 'Enabling two-factor if it is not currently enabled will immediately force you to authenticate with a Google Auth enrolled device. You will have the ability to enroll your device if one is not currently enrolled.',
'two_factor_enabled_help' => 'This will turn on two-factor authentication using Google Authenticator.',
'two_factor_optional' => 'Optional (Users can enable or disable)',
'two_factor_required' => 'Required for all users',
'two_factor_disabled' => 'Disabled',
'two_factor_enter_code' => 'Enter Two-Factor Code',
'two_factor_config_complete' => 'Submit Code',
'two_factor_enrollment_text' => "Two factor authentication is required, however your device has not been enrolled yet. Open your Google Authenticator app and scan the QR code below to enroll your device. Once you've enrolled your device, enter the code below",
'left' => 'left',
'right' => 'right',
'top' => 'top',

View file

@ -8,18 +8,18 @@ return array(
'create' => array(
'error' => 'Status Label was not created, please try again.',
'success' => 'Status Label created successfully.'
'success' => 'La etichetta di stato è creato correttamente.'
),
'update' => array(
'error' => 'Status Label was not updated, please try again',
'success' => 'Status Label updated successfully.'
'success' => 'La etichetta di stato è stato aggiornato correttamente.'
),
'delete' => array(
'confirm' => 'Are you sure you wish to delete this Status Label?',
'error' => 'There was an issue deleting the Status Label. Please try again.',
'success' => 'The Status Label was deleted successfully.'
'success' => 'L\'etichetta di stato è stata cancellata correttamente.'
)
);

View file

@ -11,7 +11,7 @@ return array(
'filetype_info' => 'I formati di file permessi sono png, gif, jpg, jpeg, doc, docx, pdf, txt, zip, e rar.',
'history_user' => 'Storico di :name',
'last_login' => 'Ultimo accesso',
'ldap_config_text' => 'LDAP configuration settings can be found Admin > Settings. The (optional) selected location will be set for all imported users.',
'ldap_config_text' => 'Le impostazioni di configurazione di LDAP possono essere trovate su Admin > Impostazioni. La posizione selezionata (facoltativa) verrà impostata per tutti gli utenti importati.',
'software_user' => 'Software estratto a :name',
'view_user' => 'Visualizza Utente :name',
'usercsv' => 'CSV file',

View file

@ -93,7 +93,7 @@
'list_all' => 'Visualizza Tutti',
'loading' => 'Caricamento',
'lock_passwords' => 'Questo campo non può essere modificato in quest\'installazione.',
'feature_disabled' => 'Questa funzione è stata disabilitata in quest\'installazione.',
'feature_disabled' => 'This feature has been disabled for the demo installation.',
'location' => 'Luogo',
'locations' => 'Luoghi',
'logout' => 'logout',
@ -151,6 +151,7 @@
'status_labels' => 'Etichetta di Stato',
'status' => 'Stato',
'suppliers' => 'Fornitori',
'submit' => 'Submit',
'total_assets' => 'Assets totali',
'total_licenses' => 'Totale licenze',
'total_accessories' => 'total accessories',

View file

@ -2,6 +2,6 @@
return [
'sent' => 'Your password link has been sent!',
'user' => 'That user does not exist or does not have an email address associated',
'user' => 'Questo utente non esiste o non ha una email associata',
];

View file

@ -33,7 +33,7 @@ return array(
"digits_between" => "il :attribute deve essere tra :min e :max digits.",
"email" => "il formato del :attribute è invalido.",
"exists" => ":attribute selezzionato è invalido.",
"email_array" => "One or more email addresses is invalid.",
"email_array" => "Una o più email sono invalidi.",
"image" => "il :attribute deve essere un immagine.",
"in" => "Il selezionato :attribute è invalido.",
"integer" => "L' :attribute deve essere un numero intero.",
@ -64,8 +64,8 @@ return array(
),
"unique" => "L' :attribute è già stato preso.",
"url" => "Il formato dell' :attribute è invalido.",
"statuslabel_type" => "You must select a valid status label type",
"unique_undeleted" => "The :attribute must be unique.",
"statuslabel_type" => "Devi selezionare un tipo di stato valido",
"unique_undeleted" => "L'attributo deve essere univoco.",
/*

View file

@ -104,6 +104,22 @@ return array(
'width_w' => 'w',
'height_h' => 'h',
'text_pt' => 'pt',
'two_factor' => 'Two Factor Authentication',
'two_factor_secret' => 'Two-Factor Code',
'two_factor_enrollment' => 'Two-Factor Enrollment',
'two_factor_enabled_text' => 'Enable Two Factor',
'two_factor_reset' => 'Reset Two-Factor Secret',
'two_factor_reset_help' => 'This will force the user to enroll their device with Google Authenticator again. This can be useful if their currently enrolled device is lost or stolen. ',
'two_factor_reset_success' => 'Two factor device successfully reset',
'two_factor_reset_error' => 'Two factor device reset failed',
'two_factor_enabled_warning' => 'Enabling two-factor if it is not currently enabled will immediately force you to authenticate with a Google Auth enrolled device. You will have the ability to enroll your device if one is not currently enrolled.',
'two_factor_enabled_help' => 'This will turn on two-factor authentication using Google Authenticator.',
'two_factor_optional' => 'Optional (Users can enable or disable)',
'two_factor_required' => 'Required for all users',
'two_factor_disabled' => 'Disabled',
'two_factor_enter_code' => 'Enter Two-Factor Code',
'two_factor_config_complete' => 'Submit Code',
'two_factor_enrollment_text' => "Two factor authentication is required, however your device has not been enrolled yet. Open your Google Authenticator app and scan the QR code below to enroll your device. Once you've enrolled your device, enter the code below",
'left' => '左',
'right' => '右',
'top' => '上',

View file

@ -93,7 +93,7 @@
'list_all' => '全ての一覧',
'loading' => '読み込み中…',
'lock_passwords' => 'このフィールドは、インストール中に編集できません。',
'feature_disabled' => 'インストール中、この機能は利用できません。',
'feature_disabled' => 'This feature has been disabled for the demo installation.',
'location' => '設置場所',
'locations' => '設置場所の数',
'logout' => 'ログアウト',
@ -151,6 +151,7 @@
'status_labels' => 'ステータスラベル',
'status' => 'ステータス',
'suppliers' => '仕入先',
'submit' => 'Submit',
'total_assets' => '資産の合計',
'total_licenses' => 'ライセンスの合計',
'total_accessories' => 'total accessories',

View file

@ -104,6 +104,22 @@ return array(
'width_w' => '넓이',
'height_h' => '높이',
'text_pt' => 'pt',
'two_factor' => 'Two Factor Authentication',
'two_factor_secret' => 'Two-Factor Code',
'two_factor_enrollment' => 'Two-Factor Enrollment',
'two_factor_enabled_text' => 'Enable Two Factor',
'two_factor_reset' => 'Reset Two-Factor Secret',
'two_factor_reset_help' => 'This will force the user to enroll their device with Google Authenticator again. This can be useful if their currently enrolled device is lost or stolen. ',
'two_factor_reset_success' => 'Two factor device successfully reset',
'two_factor_reset_error' => 'Two factor device reset failed',
'two_factor_enabled_warning' => 'Enabling two-factor if it is not currently enabled will immediately force you to authenticate with a Google Auth enrolled device. You will have the ability to enroll your device if one is not currently enrolled.',
'two_factor_enabled_help' => 'This will turn on two-factor authentication using Google Authenticator.',
'two_factor_optional' => 'Optional (Users can enable or disable)',
'two_factor_required' => 'Required for all users',
'two_factor_disabled' => 'Disabled',
'two_factor_enter_code' => 'Enter Two-Factor Code',
'two_factor_config_complete' => 'Submit Code',
'two_factor_enrollment_text' => "Two factor authentication is required, however your device has not been enrolled yet. Open your Google Authenticator app and scan the QR code below to enroll your device. Once you've enrolled your device, enter the code below",
'left' => '왼쪽',
'right' => '오른쪽',
'top' => '위',

View file

@ -93,7 +93,7 @@
'list_all' => '전체 목록보기',
'loading' => '불러오는 중',
'lock_passwords' => '이 설치에서는 이 항목을 수정할 수 없습니다.',
'feature_disabled' => '이 설정에서는 이 기능은 사용 할 수 없습니다.',
'feature_disabled' => 'This feature has been disabled for the demo installation.',
'location' => '장소',
'locations' => '위치',
'logout' => '로그아웃',
@ -151,6 +151,7 @@
'status_labels' => '상태 딱지',
'status' => '상태',
'suppliers' => '공급자',
'submit' => 'Submit',
'total_assets' => '총 자산',
'total_licenses' => '총 라이선스',
'total_accessories' => 'total accessories',

View file

@ -104,6 +104,22 @@ return array(
'width_w' => 'w',
'height_h' => 'h',
'text_pt' => 'pt',
'two_factor' => 'Two Factor Authentication',
'two_factor_secret' => 'Two-Factor Code',
'two_factor_enrollment' => 'Two-Factor Enrollment',
'two_factor_enabled_text' => 'Enable Two Factor',
'two_factor_reset' => 'Reset Two-Factor Secret',
'two_factor_reset_help' => 'This will force the user to enroll their device with Google Authenticator again. This can be useful if their currently enrolled device is lost or stolen. ',
'two_factor_reset_success' => 'Two factor device successfully reset',
'two_factor_reset_error' => 'Two factor device reset failed',
'two_factor_enabled_warning' => 'Enabling two-factor if it is not currently enabled will immediately force you to authenticate with a Google Auth enrolled device. You will have the ability to enroll your device if one is not currently enrolled.',
'two_factor_enabled_help' => 'This will turn on two-factor authentication using Google Authenticator.',
'two_factor_optional' => 'Optional (Users can enable or disable)',
'two_factor_required' => 'Required for all users',
'two_factor_disabled' => 'Disabled',
'two_factor_enter_code' => 'Enter Two-Factor Code',
'two_factor_config_complete' => 'Submit Code',
'two_factor_enrollment_text' => "Two factor authentication is required, however your device has not been enrolled yet. Open your Google Authenticator app and scan the QR code below to enroll your device. Once you've enrolled your device, enter the code below",
'left' => 'left',
'right' => 'right',
'top' => 'top',

View file

@ -93,7 +93,7 @@
'list_all' => 'Parodyti viską',
'loading' => 'Įkeliama',
'lock_passwords' => 'Šis laukelis negali būti keičiamas šiame diegime.',
'feature_disabled' => 'Šis pasirinkimas buvo atjungtas šiame diegime.',
'feature_disabled' => 'This feature has been disabled for the demo installation.',
'location' => 'Vieta',
'locations' => 'Vietovės',
'logout' => 'Atsijungti',
@ -151,6 +151,7 @@
'status_labels' => 'Būklės kortelės',
'status' => 'Būklė',
'suppliers' => 'Tiekėjai',
'submit' => 'Submit',
'total_assets' => 'įrangos iš viso',
'total_licenses' => 'iš viso licenzijų',
'total_accessories' => 'total accessories',

View file

@ -104,6 +104,22 @@ return array(
'width_w' => 'w',
'height_h' => 'h',
'text_pt' => 'pt',
'two_factor' => 'Two Factor Authentication',
'two_factor_secret' => 'Two-Factor Code',
'two_factor_enrollment' => 'Two-Factor Enrollment',
'two_factor_enabled_text' => 'Enable Two Factor',
'two_factor_reset' => 'Reset Two-Factor Secret',
'two_factor_reset_help' => 'This will force the user to enroll their device with Google Authenticator again. This can be useful if their currently enrolled device is lost or stolen. ',
'two_factor_reset_success' => 'Two factor device successfully reset',
'two_factor_reset_error' => 'Two factor device reset failed',
'two_factor_enabled_warning' => 'Enabling two-factor if it is not currently enabled will immediately force you to authenticate with a Google Auth enrolled device. You will have the ability to enroll your device if one is not currently enrolled.',
'two_factor_enabled_help' => 'This will turn on two-factor authentication using Google Authenticator.',
'two_factor_optional' => 'Optional (Users can enable or disable)',
'two_factor_required' => 'Required for all users',
'two_factor_disabled' => 'Disabled',
'two_factor_enter_code' => 'Enter Two-Factor Code',
'two_factor_config_complete' => 'Submit Code',
'two_factor_enrollment_text' => "Two factor authentication is required, however your device has not been enrolled yet. Open your Google Authenticator app and scan the QR code below to enroll your device. Once you've enrolled your device, enter the code below",
'left' => 'left',
'right' => 'right',
'top' => 'top',

View file

@ -93,7 +93,7 @@
'list_all' => 'Senaraikan Semua',
'loading' => 'Loading',
'lock_passwords' => 'This field cannot be edited in this installation.',
'feature_disabled' => 'This feature has been disabled for this installation.',
'feature_disabled' => 'This feature has been disabled for the demo installation.',
'location' => 'Lokasi',
'locations' => 'Lokasi',
'logout' => 'Log keluar',
@ -151,6 +151,7 @@
'status_labels' => 'Label Status',
'status' => 'Status',
'suppliers' => 'Pembekal',
'submit' => 'Submit',
'total_assets' => 'jumlah harta',
'total_licenses' => 'jumlah lesen',
'total_accessories' => 'total accessories',

View file

@ -104,6 +104,22 @@ return array(
'width_w' => 'b',
'height_h' => 'h',
'text_pt' => 'pt',
'two_factor' => 'Two Factor Authentication',
'two_factor_secret' => 'Two-Factor Code',
'two_factor_enrollment' => 'Two-Factor Enrollment',
'two_factor_enabled_text' => 'Enable Two Factor',
'two_factor_reset' => 'Reset Two-Factor Secret',
'two_factor_reset_help' => 'This will force the user to enroll their device with Google Authenticator again. This can be useful if their currently enrolled device is lost or stolen. ',
'two_factor_reset_success' => 'Two factor device successfully reset',
'two_factor_reset_error' => 'Two factor device reset failed',
'two_factor_enabled_warning' => 'Enabling two-factor if it is not currently enabled will immediately force you to authenticate with a Google Auth enrolled device. You will have the ability to enroll your device if one is not currently enrolled.',
'two_factor_enabled_help' => 'This will turn on two-factor authentication using Google Authenticator.',
'two_factor_optional' => 'Optional (Users can enable or disable)',
'two_factor_required' => 'Required for all users',
'two_factor_disabled' => 'Disabled',
'two_factor_enter_code' => 'Enter Two-Factor Code',
'two_factor_config_complete' => 'Submit Code',
'two_factor_enrollment_text' => "Two factor authentication is required, however your device has not been enrolled yet. Open your Google Authenticator app and scan the QR code below to enroll your device. Once you've enrolled your device, enter the code below",
'left' => 'links',
'right' => 'rechts',
'top' => 'bovenkant',

View file

@ -93,7 +93,7 @@
'list_all' => 'Toon Alles',
'loading' => 'Bezig met laden',
'lock_passwords' => 'Dit veld kan niet worden bewerkt met deze installatie.',
'feature_disabled' => 'Deze functie is uitgeschakeld voor deze installatie.',
'feature_disabled' => 'This feature has been disabled for the demo installation.',
'location' => 'Locatie',
'locations' => 'Locaties',
'logout' => 'Afmelden',
@ -151,6 +151,7 @@
'status_labels' => 'Statuslabels',
'status' => 'Status',
'suppliers' => 'Leveranciers',
'submit' => 'Submit',
'total_assets' => 'totaal aantal materialen',
'total_licenses' => 'Totale licenties',
'total_accessories' => 'totaal aantal accessoires',

View file

@ -21,15 +21,15 @@ return array(
),
'checkout' => array(
'error' => 'Component was not checked out, please try again',
'success' => 'Component checked out successfully.',
'user_does_not_exist' => 'That user is invalid. Please try again.'
'error' => 'Komponent ble ikke sjekket ut. Prøv igjen',
'success' => 'Vellykket utsjekk av komponent.',
'user_does_not_exist' => 'Denne brukeren er ugyldig. Vennligst prøv igjen.'
),
'checkin' => array(
'error' => 'Component was not checked in, please try again',
'success' => 'Component checked in successfully.',
'user_does_not_exist' => 'That user is invalid. Please try again.'
'error' => 'Komponenten ble ikke sjekket inn, vennligst prøv igjen',
'success' => 'Vellykket innsjekk av komponent.',
'user_does_not_exist' => 'Denne brukeren er ugyldig. Prøv igjen.'
)

Some files were not shown because too many files have changed in this diff Show more