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']) !!} +
+
+