From c7a56d17535acd5901d7d1802eeffac8a633bf95 Mon Sep 17 00:00:00 2001 From: Andy Heathershaw Date: Tue, 6 Sep 2016 12:23:14 +0100 Subject: [PATCH] Added mail settings for SMTP. Configuration values that are the same as the defaults are no longer saved to the database (and are purged if changed to the default.) Started adding a "test mail config" settings function --- app/Helpers/ConfigHelper.php | 16 +++++- app/Helpers/ThemeHelper.php | 7 ++- .../Controllers/Admin/DefaultController.php | 26 ++++++++- app/Http/Controllers/Auth/LoginController.php | 11 ++++ .../Controllers/Auth/RegisterController.php | 55 +++++++++++++++---- app/Mail/TestMailConfig.php | 35 ++++++++++++ app/Mail/UserActivationRequired.php | 44 +++++++++++++++ app/Providers/AppServiceProvider.php | 16 ++++++ app/User.php | 4 +- config/mail.php | 24 +++++--- ..._06_102806_add_user_activation_columns.php | 36 ++++++++++++ resources/lang/en/email.php | 5 ++ .../themes/base/admin/settings.blade.php | 37 +++++++++++++ .../email/user_activation_required.blade.php | 6 ++ 14 files changed, 294 insertions(+), 28 deletions(-) create mode 100644 app/Mail/TestMailConfig.php create mode 100644 app/Mail/UserActivationRequired.php create mode 100644 database/migrations/2016_09_06_102806_add_user_activation_columns.php create mode 100644 resources/lang/en/email.php create mode 100644 resources/views/themes/base/email/user_activation_required.blade.php diff --git a/app/Helpers/ConfigHelper.php b/app/Helpers/ConfigHelper.php index 8133ed7..83de8f1 100644 --- a/app/Helpers/ConfigHelper.php +++ b/app/Helpers/ConfigHelper.php @@ -51,11 +51,17 @@ class ConfigHelper public function defaults() { + $currentAppName = $this->get('app_name', false); + return array( 'allow_self_registration' => true, 'app_name' => trans('global.app_name'), 'date_format' => $this->allowedDateFormats()[0], - 'require_email_verification' => true + 'require_email_verification' => true, + 'sender_address' => sprintf('hostmaster@%s', (isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : 'localhost')), + 'sender_name' => (is_null($currentAppName) ? trans('global.app_name') : $currentAppName), + 'smtp_server' => 'localhost', + 'smtp_port' => 25 ); } @@ -63,7 +69,13 @@ class ConfigHelper { $config = Configuration::where('key', $key)->first(); - return (is_null($config) ? $this->defaults()[$key] : $config->value); + if (is_null($config)) + { + $defaults = $this->defaults(); + return ($defaultIfUnset && isset($defaults[$key]) ? $defaults[$key] : null); + } + + return $config->value; } public function getAll() diff --git a/app/Helpers/ThemeHelper.php b/app/Helpers/ThemeHelper.php index 7165df1..db75587 100644 --- a/app/Helpers/ThemeHelper.php +++ b/app/Helpers/ThemeHelper.php @@ -32,6 +32,11 @@ class ThemeHelper } public function render($viewPath, array $viewData = array()) + { + return view($this->viewName($viewPath), $viewData); + } + + public function viewName($viewPath) { $themeName = $this->getThemeName(); @@ -46,7 +51,7 @@ class ThemeHelper $themeName = ThemeHelper::DEFAULT_THEME; } - return view(sprintf('themes.%s.%s', $themeName, $viewPath), $viewData); + return sprintf('themes.%s.%s', $themeName, $viewPath); } private function getRealFilePath($themeName, $viewPath) diff --git a/app/Http/Controllers/Admin/DefaultController.php b/app/Http/Controllers/Admin/DefaultController.php index 46ec2cb..ff14f73 100644 --- a/app/Http/Controllers/Admin/DefaultController.php +++ b/app/Http/Controllers/Admin/DefaultController.php @@ -32,26 +32,46 @@ class DefaultController extends Controller { $checkboxKeys = [ 'allow_self_registration', - 'require_email_verification' + 'require_email_verification', ]; $updateKeys = [ 'app_name', 'date_format', + 'sender_address', + 'sender_name', 'theme' ]; + $defaults = UserConfig::defaults(); + foreach ($updateKeys as $key) { $config = UserConfig::getOrCreateModel($key); $config->value = $request->request->get($key); - $config->save(); + + if (isset($defaults[$key]) && $defaults[$key] == $config->value) + { + $config->delete(); + } + else + { + $config->save(); + } } foreach ($checkboxKeys as $key) { $config = UserConfig::getOrCreateModel($key); $config->value = ($request->request->get($key) == 'on' ? 1 : 0); - $config->save(); + + if (isset($defaults[$key]) && $defaults[$key] == $config->value) + { + $config->delete(); + } + else + { + $config->save(); + } } $request->session()->flash('success', trans('admin.settings_saved_message')); diff --git a/app/Http/Controllers/Auth/LoginController.php b/app/Http/Controllers/Auth/LoginController.php index 4007525..c323e5f 100644 --- a/app/Http/Controllers/Auth/LoginController.php +++ b/app/Http/Controllers/Auth/LoginController.php @@ -5,6 +5,7 @@ namespace App\Http\Controllers\Auth; use App\Facade\Theme; use App\Http\Controllers\Controller; use Illuminate\Foundation\Auth\AuthenticatesUsers; +use Illuminate\Http\Request; class LoginController extends Controller { @@ -38,6 +39,16 @@ class LoginController extends Controller $this->middleware('guest', ['except' => 'logout']); } + protected function credentials(Request $request) + { + $result = $request->only($this->username(), 'password'); + + // Only allow activated users to login + $result['is_activated'] = true; + + return $result; + } + /** * Show the application's login form. * diff --git a/app/Http/Controllers/Auth/RegisterController.php b/app/Http/Controllers/Auth/RegisterController.php index 6d87798..b285db3 100644 --- a/app/Http/Controllers/Auth/RegisterController.php +++ b/app/Http/Controllers/Auth/RegisterController.php @@ -4,7 +4,11 @@ namespace App\Http\Controllers\Auth; use App\Facade\Theme; use App\Facade\UserConfig; +use App\Helpers\MiscHelper; +use App\Mail\UserActivationRequired; use App\User; +use Illuminate\Http\Request; +use Illuminate\Support\Facades\Mail; use Validator; use App\Http\Controllers\Controller; use Illuminate\Foundation\Auth\RegistersUsers; @@ -64,21 +68,50 @@ class RegisterController extends Controller */ protected function create(array $data) { - return User::create([ - 'name' => $data['name'], - 'email' => $data['email'], - 'password' => bcrypt($data['password']), - ]); + $activationData = [ + 'is_activated' => true + ]; + + if (UserConfig::get('require_email_verification')) + { + $activationData['is_activated'] = false; + $activationData['activation_code'] = MiscHelper::randomString(); + } + + return User::create(array_merge( + [ + 'name' => $data['name'], + 'email' => $data['email'], + 'password' => bcrypt($data['password']), + 'is_admin' => false + ], + $activationData + )); } public function register(Request $request) { - if (UserConfig::get('allow_self_registration') == 1) + if (!UserConfig::get('allow_self_registration')) { - return parent::register($request); + return redirect(route('home')); } - return redirect(route('home')); + $this->validator($request->all())->validate(); + + /** @var User $user */ + $user = $this->create($request->all()); + + if ($user->is_activated) + { + $this->guard()->login($user); + } + else + { + // Send activation e-mail + Mail::to($user)->send(new UserActivationRequired($user)); + } + + return redirect($this->redirectPath()); } /** @@ -88,11 +121,11 @@ class RegisterController extends Controller */ public function showRegistrationForm() { - if (UserConfig::get('allow_self_registration') == 1) + if (!UserConfig::get('allow_self_registration')) { - return Theme::render('auth.register'); + return redirect(route('home')); } - return redirect(route('home')); + return Theme::render('auth.register'); } } diff --git a/app/Mail/TestMailConfig.php b/app/Mail/TestMailConfig.php new file mode 100644 index 0000000..938e1f2 --- /dev/null +++ b/app/Mail/TestMailConfig.php @@ -0,0 +1,35 @@ +from(UserConfig::get('sender_address'), UserConfig::get('sender_name')) + ->subject(trans('email.test_email_subject', ['app_name' => UserConfig::get('app_name')])) + ->view(Theme::viewName('email.test_email')); + } +} diff --git a/app/Mail/UserActivationRequired.php b/app/Mail/UserActivationRequired.php new file mode 100644 index 0000000..abf6565 --- /dev/null +++ b/app/Mail/UserActivationRequired.php @@ -0,0 +1,44 @@ +user = $user; + } + + /** + * Build the message. + * + * @return $this + */ + public function build() + { + return $this + ->from(UserConfig::get('sender_address'), UserConfig::get('sender_name')) + ->subject(trans('email.activation_required_subject', ['app_name' => UserConfig::get('app_name')])) + ->view(Theme::viewName('email.user_activation_required')) + ->with([ + 'user' => $this->user + ]); + } +} diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index 65d9f7d..fd78b8a 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -40,6 +40,9 @@ class AppServiceProvider extends ServiceProvider $this->addThemeInfoToView(); $this->addAlbumsToView(); } + + // Set the default mail configuration as per user's requirements + $this->updateMailConfig(); } /** @@ -72,4 +75,17 @@ class AppServiceProvider extends ServiceProvider // Also add a theme_url key View::share('theme_url', sprintf('themes/%s', Theme::current())); } + + private function updateMailConfig() + { + /** @var \Swift_Mailer $swiftMailer */ + $swiftMailer = $this->app->mailer->getSwiftMailer(); + + /** @var \Swift_SmtpTransport $transport */ + $transport = $swiftMailer->getTransport(); + $transport->setHost(UserConfig::get('smtp_server')); + $transport->setPort(intval(UserConfig::get('smtp_port'))); + $transport->setUsername(UserConfig::get('smtp_username')); + $transport->setPassword(UserConfig::get('smtp_password')); + } } diff --git a/app/User.php b/app/User.php index 20078d4..e46b31c 100644 --- a/app/User.php +++ b/app/User.php @@ -15,7 +15,7 @@ class User extends Authenticatable * @var array */ protected $fillable = [ - 'name', 'email', 'password', 'is_admin' + 'name', 'email', 'password', 'is_admin', 'is_activated', 'activation_token' ]; /** @@ -24,6 +24,6 @@ class User extends Authenticatable * @var array */ protected $hidden = [ - 'password', 'remember_token', + 'password', 'remember_token', 'activation_token' ]; } diff --git a/config/mail.php b/config/mail.php index 9d4c4d8..be962b7 100644 --- a/config/mail.php +++ b/config/mail.php @@ -1,5 +1,11 @@ env('MAIL_DRIVER', 'smtp'), + 'driver' => 'smtp', /* |-------------------------------------------------------------------------- @@ -29,7 +35,7 @@ return [ | */ - 'host' => env('MAIL_HOST', 'smtp.mailgun.org'), + 'host' => '', /* |-------------------------------------------------------------------------- @@ -42,7 +48,7 @@ return [ | */ - 'port' => env('MAIL_PORT', 587), + 'port' => 0, /* |-------------------------------------------------------------------------- @@ -56,8 +62,8 @@ return [ */ 'from' => [ - 'address' => 'hello@example.com', - 'name' => 'Example', + 'address' => '', + 'name' => '', ], /* @@ -71,7 +77,7 @@ return [ | */ - 'encryption' => env('MAIL_ENCRYPTION', 'tls'), + 'encryption' => '', /* |-------------------------------------------------------------------------- @@ -84,7 +90,7 @@ return [ | */ - 'username' => env('MAIL_USERNAME'), + 'username' => '', /* |-------------------------------------------------------------------------- @@ -97,7 +103,7 @@ return [ | */ - 'password' => env('MAIL_PASSWORD'), + 'password' => '', /* |-------------------------------------------------------------------------- @@ -110,6 +116,6 @@ return [ | */ - 'sendmail' => '/usr/sbin/sendmail -bs', + 'sendmail' => '', ]; diff --git a/database/migrations/2016_09_06_102806_add_user_activation_columns.php b/database/migrations/2016_09_06_102806_add_user_activation_columns.php new file mode 100644 index 0000000..7d49d24 --- /dev/null +++ b/database/migrations/2016_09_06_102806_add_user_activation_columns.php @@ -0,0 +1,36 @@ +boolean('is_activated'); + $table->string('activation_token')->nullable(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('users', function (Blueprint $table) + { + $table->dropColumn('is_activated'); + $table->dropColumn('activation_token'); + }); + } +} diff --git a/resources/lang/en/email.php b/resources/lang/en/email.php new file mode 100644 index 0000000..ada4b43 --- /dev/null +++ b/resources/lang/en/email.php @@ -0,0 +1,5 @@ + 'Activate your :app_name account', + 'test_email_subject' => 'Test e-mail from :app_name' +]; \ No newline at end of file diff --git a/resources/views/themes/base/admin/settings.blade.php b/resources/views/themes/base/admin/settings.blade.php index 8625844..fe910c9 100644 --- a/resources/views/themes/base/admin/settings.blade.php +++ b/resources/views/themes/base/admin/settings.blade.php @@ -14,6 +14,7 @@ {{-- Nav tabs --}} @@ -44,6 +45,42 @@ +
+
+ {!! Form::label('sender_name', 'Sender name:', ['class' => 'control-label']) !!} + {!! Form::text('sender_name', old('sender_name'), ['class' => 'form-control']) !!} +
+ +
+ {!! Form::label('sender_address', 'Sender address:', ['class' => 'control-label']) !!} + {!! Form::text('sender_address', old('sender_address'), ['class' => 'form-control']) !!} +
+ +
+ +

Configure your SMTP server using the settings below.

+ +
+ {!! Form::label('smtp_server', 'Hostname:', ['class' => 'control-label']) !!} + {!! Form::text('smtp_server', old('smtp_server'), ['class' => 'form-control']) !!} +
+ +
+ {!! Form::label('smtp_port', 'Port:', ['class' => 'control-label']) !!} + {!! Form::text('smtp_port', old('smtp_port'), ['class' => 'form-control']) !!} +
+ +
+ {!! Form::label('smtp_username', 'Username:', ['class' => 'control-label']) !!} + {!! Form::text('smtp_username', old('smtp_username'), ['class' => 'form-control']) !!} +
+ +
+ {!! Form::label('smtp_password', 'Password:', ['class' => 'control-label']) !!} + {!! Form::text('smtp_password', old('smtp_password'), ['class' => 'form-control']) !!} +
+
+