mirror of
https://github.com/snipe/snipe-it.git
synced 2025-10-29 11:21:21 +00:00
Merge remote-tracking branch 'origin/develop'
This commit is contained in:
commit
fe15dacb1f
@ -168,6 +168,7 @@ AWS_DEFAULT_REGION=null
|
||||
LOGIN_MAX_ATTEMPTS=5
|
||||
LOGIN_LOCKOUT_DURATION=60
|
||||
RESET_PASSWORD_LINK_EXPIRES=900
|
||||
INVITE_PASSWORD_LINK_EXPIRES=1500
|
||||
|
||||
# --------------------------------------------
|
||||
# OPTIONAL: MISC
|
||||
|
||||
@ -174,6 +174,7 @@ LOGIN_AUTOCOMPLETE=false
|
||||
RESET_PASSWORD_LINK_EXPIRES=15
|
||||
PASSWORD_CONFIRM_TIMEOUT=10800
|
||||
PASSWORD_RESET_MAX_ATTEMPTS_PER_MIN=50
|
||||
INVITE_PASSWORD_LINK_EXPIRES=1500
|
||||
|
||||
# --------------------------------------------
|
||||
# OPTIONAL: MISC
|
||||
|
||||
@ -13,7 +13,6 @@ use App\Models\Company;
|
||||
use App\Models\Group;
|
||||
use App\Models\Setting;
|
||||
use App\Models\User;
|
||||
use App\Notifications\WelcomeNotification;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Database\Eloquent\ModelNotFoundException;
|
||||
use Illuminate\Http\Request;
|
||||
@ -142,18 +141,6 @@ class UsersController extends Controller
|
||||
$user->groups()->sync([]);
|
||||
}
|
||||
|
||||
if (($request->input('email_user') == 1) && ($request->filled('email'))) {
|
||||
// Send the credentials through email
|
||||
$data = [];
|
||||
$data['email'] = e($request->input('email'));
|
||||
$data['username'] = e($request->input('username'));
|
||||
$data['first_name'] = e($request->input('first_name'));
|
||||
$data['last_name'] = e($request->input('last_name'));
|
||||
$data['password'] = e($request->input('password'));
|
||||
|
||||
$user->notify(new WelcomeNotification($data));
|
||||
}
|
||||
|
||||
return Helper::getRedirectOption($request, $user->id, 'Users')
|
||||
->with('success', trans('admin/users/message.success.create'));
|
||||
}
|
||||
|
||||
@ -133,7 +133,7 @@ abstract class Importer
|
||||
} else {
|
||||
$this->csv = Reader::createFromString($file);
|
||||
}
|
||||
$this->tempPassword = substr(str_shuffle('0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'), 0, 40);
|
||||
$this->tempPassword = '*** NO PASSWORD - IMPORTED VIA CSV ***';
|
||||
}
|
||||
|
||||
// Cached Values for import lookups
|
||||
|
||||
@ -8,6 +8,7 @@ use App\Models\Setting;
|
||||
use App\Models\User;
|
||||
use App\Notifications\WelcomeNotification;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Password;
|
||||
|
||||
/**
|
||||
* This is ONLY used for the User Import. When we are importing users
|
||||
@ -110,7 +111,7 @@ class UserImporter extends ItemImporter
|
||||
|
||||
// This needs to be applied after the update logic, otherwise we'll overwrite user passwords
|
||||
// Issue #5408
|
||||
$this->item['password'] = bcrypt($this->tempPassword);
|
||||
$this->item['password'] = $this->tempPassword;
|
||||
|
||||
$this->log('No matching user, creating one');
|
||||
$user = new User();
|
||||
@ -121,17 +122,17 @@ class UserImporter extends ItemImporter
|
||||
$this->log('User '.$this->item['name'].' was created');
|
||||
|
||||
if (($user->email) && ($user->activated == '1')) {
|
||||
$data = [
|
||||
'email' => $user->email,
|
||||
'username' => $user->username,
|
||||
'first_name' => $user->first_name,
|
||||
'last_name' => $user->last_name,
|
||||
'password' => $this->tempPassword,
|
||||
];
|
||||
|
||||
if ($this->send_welcome) {
|
||||
$user->notify(new WelcomeNotification($data));
|
||||
|
||||
try {
|
||||
$user->notify(new WelcomeNotification($user));
|
||||
} catch (\Exception $e) {
|
||||
Log::warning('Could not send welcome notification for user: ' . $e->getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
$user = null;
|
||||
$this->item = null;
|
||||
@ -140,7 +141,6 @@ class UserImporter extends ItemImporter
|
||||
}
|
||||
|
||||
$this->logError($user, 'User');
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -5,26 +5,23 @@ namespace App\Notifications;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Notifications\Messages\MailMessage;
|
||||
use Illuminate\Notifications\Notification;
|
||||
use Illuminate\Support\Facades\Password;
|
||||
use App\Models\User;
|
||||
|
||||
class WelcomeNotification extends Notification
|
||||
{
|
||||
use Queueable;
|
||||
|
||||
private $_data = [];
|
||||
|
||||
public $expire_date;
|
||||
/**
|
||||
* Create a new notification instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(array $content)
|
||||
public function __construct(public User $user)
|
||||
{
|
||||
$this->_data['email'] = htmlspecialchars_decode($content['email']);
|
||||
$this->_data['first_name'] = htmlspecialchars_decode($content['first_name']);
|
||||
$this->_data['last_name'] = htmlspecialchars_decode($content['last_name']);
|
||||
$this->_data['username'] = htmlspecialchars_decode($content['username']);
|
||||
$this->_data['password'] = htmlspecialchars_decode($content['password']);
|
||||
$this->_data['url'] = config('app.url');
|
||||
$this->user->token = Password::broker('invites')->createToken($user);
|
||||
$this->user->expire_date = now()->addMinutes((int) config('auth.passwords.invites.expire', 2880))->format('F j, Y, g:i a');
|
||||
}
|
||||
|
||||
/**
|
||||
@ -44,8 +41,9 @@ class WelcomeNotification extends Notification
|
||||
*/
|
||||
public function toMail()
|
||||
{
|
||||
|
||||
return (new MailMessage())
|
||||
->subject(trans('mail.welcome', ['name' => $this->_data['first_name'].' '.$this->_data['last_name']]))
|
||||
->markdown('notifications.Welcome', $this->_data);
|
||||
->subject(trans('mail.welcome', ['name' => $this->user->first_name.' '.$this->user->last_name]))
|
||||
->markdown('notifications.Welcome', $this->user->toArray());
|
||||
}
|
||||
}
|
||||
|
||||
@ -104,6 +104,16 @@ return [
|
||||
]
|
||||
|
||||
],
|
||||
|
||||
'invites' => [
|
||||
'provider' => 'users',
|
||||
'table' => 'password_resets',
|
||||
'expire' => env('INVITE_PASSWORD_LINK_EXPIRES', 2880),
|
||||
'throttle' => [
|
||||
'max_attempts' => env('LOGIN_MAX_ATTEMPTS', 5),
|
||||
'lockout_duration' => env('LOGIN_LOCKOUT_DURATION', 60),
|
||||
]
|
||||
],
|
||||
],
|
||||
|
||||
/*
|
||||
|
||||
@ -51,8 +51,6 @@ class AssetModelSeeder extends Seeder
|
||||
$del_files = Storage::files($dst);
|
||||
|
||||
foreach ($del_files as $del_file) { // iterate files
|
||||
$file_to_delete = str_replace($src, '', $del_file);
|
||||
Log::debug('Deleting: '.$file_to_delete);
|
||||
try {
|
||||
Storage::disk('public')->delete($dst.$del_file);
|
||||
} catch (\Exception $e) {
|
||||
@ -63,7 +61,6 @@ class AssetModelSeeder extends Seeder
|
||||
$add_files = glob($src.'/*.*');
|
||||
foreach ($add_files as $add_file) {
|
||||
$file_to_copy = str_replace($src, '', $add_file);
|
||||
Log::debug('Copying: '.$file_to_copy);
|
||||
try {
|
||||
Storage::disk('public')->put($dst.$file_to_copy, file_get_contents($src.$file_to_copy));
|
||||
} catch (\Exception $e) {
|
||||
|
||||
@ -10,9 +10,11 @@ return [
|
||||
'forgot_password' => 'I forgot my password',
|
||||
'ldap_reset_password' => 'Please click here to reset your LDAP password',
|
||||
'remember_me' => 'Remember Me',
|
||||
'username_help_top' => 'Enter your <strong>username</strong> to be emailed a password reset link.',
|
||||
'username_help_top' => 'Enter your <strong>username</strong> to be emailed a password reset link.',
|
||||
'username_help_bottom' => 'Your username and email address <em>may</em> be the same, but may not be, depending on your configuration. If you cannot remember your username, contact your administrator. <br><br><strong>Usernames without an associated email address will not be emailed a password reset link.</strong> ',
|
||||
'google_login' => 'Login with Google Workspace',
|
||||
'google_login_failed' => 'Google Login failed, please try again.',
|
||||
'invite_password_expires' => 'This password reset link will expire on :expire_date. You can use the manual password reset link to receive a new reset token by clicking here',
|
||||
|
||||
];
|
||||
|
||||
|
||||
@ -596,6 +596,7 @@ return [
|
||||
'version' => 'Version',
|
||||
'build' => 'build',
|
||||
'footer_credit' => '<a target="_blank" href="https://snipeitapp.com" rel="noopener">Snipe-IT</a> is open source software, made with <i class="fa fa-heart" aria-hidden="true" style="color: #a94442; font-size: 10px" /></i><span class="sr-only">love</span> by <a href="https://bsky.app/profile/snipeitapp.com" rel="noopener">@snipeitapp.com</a>.',
|
||||
'set_password' => 'Set a Password',
|
||||
|
||||
// Add form placeholders here
|
||||
'placeholders' => [
|
||||
|
||||
@ -33,7 +33,7 @@ return [
|
||||
'send_pdf_copy' => 'Send a copy of this acceptance to my email address',
|
||||
'accessory_name' => 'Accessory Name',
|
||||
'additional_notes' => 'Additional Notes',
|
||||
'admin_has_created' => 'An administrator has created an account for you on the :web website.',
|
||||
'admin_has_created' => 'An administrator has created an account for you on the :web website. Please find your username below, and click on the link to set a password.',
|
||||
'asset' => 'Asset',
|
||||
'asset_name' => 'Asset Name',
|
||||
'asset_requested' => 'Asset requested',
|
||||
|
||||
@ -33,7 +33,7 @@
|
||||
<table class="table table-striped table-bordered" id="errors-table">
|
||||
<thead>
|
||||
<th>{{ trans('general.item') }}</th>
|
||||
<th>Field</th>
|
||||
<th>{{ trans('admin/custom_fields/general.field') }}</th>
|
||||
<th>{{ trans('general.error') }}</th>
|
||||
</thead>
|
||||
<tbody>
|
||||
@ -191,7 +191,7 @@
|
||||
|
||||
|
||||
|
||||
@if (($typeOfImport != 'location' && $typeOfImport!= 'assetModel' && $typeOfImport!= 'component' && $typeOfImport!= 'supplier') && $typeOfImport!= 'manufacturer' && $typeOfImport!= 'category' && ($typeOfImport!=''))
|
||||
@if ($typeOfImport === 'user')
|
||||
<label class="form-control">
|
||||
<input type="checkbox" name="send_welcome" data-livewire-component="{{ $this->getId() }}" wire:model.live="send_welcome">
|
||||
{{ trans('general.send_welcome_email_to_users') }}
|
||||
|
||||
@ -3,13 +3,16 @@
|
||||
|
||||
{{ trans('mail.admin_has_created', ['web' => $snipeSettings->site_name]) }}
|
||||
|
||||
{{ trans('mail.login') }}: {{ $username }} <br>
|
||||
{{ trans('mail.password') }}: {{ $password }}
|
||||
<strong>{{ trans('mail.username') }}: </strong> {{ $username }}<br>
|
||||
|
||||
@component('mail::button', ['url' => $url])
|
||||
Go To {{$snipeSettings->site_name}}
|
||||
@component('mail::button',
|
||||
['url' => url(route('password.reset', ['token' => $token, 'email' => $email]))])
|
||||
{{ trans('general.set_password') }}
|
||||
@endcomponent
|
||||
|
||||
<p>{{ trans('auth/general.invite_password_expires', ['expire_date' => $expire_date]) }}: <a href="{{ url(route('password.request')) }}">{{ url(route('password.request')) }}</a>
|
||||
</p>
|
||||
|
||||
{{ trans('mail.best_regards') }} <br>
|
||||
@if ($snipeSettings->show_url_in_emails=='1')
|
||||
<p><a href="{{ config('app.url') }}">{{ $snipeSettings->site_name }}</a></p>
|
||||
|
||||
@ -250,26 +250,7 @@
|
||||
{!! $errors->first('email', '<span class="alert-msg" aria-hidden="true">:message</span>') !!}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Email user -->
|
||||
@if (!$user->id)
|
||||
<div class="form-group" id="email_user_row">
|
||||
|
||||
<div class="col-md-8 col-md-offset-3">
|
||||
<label class="form-control form-control--disabled">
|
||||
|
||||
<input type="checkbox" name="email_user" value="1" id="email_user_checkbox" @checked(old('email_user')) aria-label="email_user">
|
||||
|
||||
{{ trans('admin/users/general.email_user_creds_on_create') }}
|
||||
</label>
|
||||
|
||||
<p class="help-block"> {{ trans('admin/users/general.send_email_help') }}</p>
|
||||
|
||||
</div>
|
||||
</div> <!--/form-group-->
|
||||
@endif
|
||||
|
||||
|
||||
@include ('partials.forms.edit.image-upload', ['fieldname' => 'avatar', 'image_path' => app('users_upload_path')])
|
||||
|
||||
|
||||
@ -617,39 +598,8 @@
|
||||
$(document).ready(function() {
|
||||
|
||||
|
||||
// If the "user can login" check box is checked, show them the ability to email the user credentials
|
||||
$("#activated").change(function() {
|
||||
if (this.checked) {
|
||||
$("#email_user_row").show();
|
||||
} else {
|
||||
$("#email_user_row").hide();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// Set some defaults
|
||||
$('#email_user_checkbox').prop("disabled", true);
|
||||
$('#email_user_checkbox').prop("checked", false);
|
||||
$("#email_user_checkbox").removeAttr('checked');
|
||||
|
||||
// If the email address is longer than 5 characters, enable the "send email" checkbox
|
||||
$('#email').on('keyup',function(){
|
||||
//event.preventDefault();
|
||||
|
||||
@if (!config('app.lock_passwords'))
|
||||
|
||||
if (this.value.length > 5){
|
||||
$('#email_user_checkbox').prop("disabled", false);
|
||||
$("#email_user_checkbox").parent().removeClass("form-control--disabled");
|
||||
} else {
|
||||
$('#email_user_checkbox').prop("disabled", true);
|
||||
$('#email_user_checkbox').prop("checked", false);
|
||||
$("#email_user_checkbox").parent().addClass("form-control--disabled");
|
||||
}
|
||||
|
||||
@endif
|
||||
});
|
||||
|
||||
|
||||
// Check/Uncheck all radio buttons in the group
|
||||
$('tr.header-row input:radio').change(function() {
|
||||
|
||||
@ -82,7 +82,7 @@ class ImportUsersTest extends ImportDataTestCase implements TestsPermissionsRequ
|
||||
$this->assertEquals($row['location'], $newUser->location->name);
|
||||
$this->assertEquals($row['phoneNumber'], $newUser->phone);
|
||||
$this->assertEquals($row['position'], $newUser->jobtitle);
|
||||
$this->assertTrue(Hash::isHashed($newUser->password));
|
||||
$this->assertFalse(Hash::isHashed($newUser->password));
|
||||
$this->assertEquals('', $newUser->website);
|
||||
$this->assertEquals('', $newUser->country);
|
||||
$this->assertEquals('', $newUser->address);
|
||||
@ -298,7 +298,7 @@ class ImportUsersTest extends ImportDataTestCase implements TestsPermissionsRequ
|
||||
$this->assertEquals($row['username'], $newUser->company->name);
|
||||
$this->assertEquals($row['firstName'], $newUser->location->name);
|
||||
$this->assertEquals($row['employeeNumber'], $newUser->phone);
|
||||
$this->assertTrue(Hash::isHashed($newUser->password));
|
||||
$this->assertFalse(Hash::isHashed($newUser->password));
|
||||
$this->assertEquals('', $newUser->website);
|
||||
$this->assertEquals('', $newUser->country);
|
||||
$this->assertEquals('', $newUser->address);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user