Showing
17 changed files
with
370 additions
and
10 deletions
app/EmailConfirmation.php
0 → 100644
app/Exceptions/UserRegistrationException.php
0 → 100644
| ... | @@ -2,7 +2,12 @@ | ... | @@ -2,7 +2,12 @@ |
| 2 | 2 | ||
| 3 | namespace Oxbow\Http\Controllers\Auth; | 3 | namespace Oxbow\Http\Controllers\Auth; |
| 4 | 4 | ||
| 5 | +use Illuminate\Http\Request; | ||
| 5 | use Oxbow\Exceptions\SocialSignInException; | 6 | use Oxbow\Exceptions\SocialSignInException; |
| 7 | +use Oxbow\Exceptions\UserRegistrationException; | ||
| 8 | +use Oxbow\Repos\UserRepo; | ||
| 9 | +use Oxbow\Services\EmailConfirmationService; | ||
| 10 | +use Oxbow\Services\Facades\Setting; | ||
| 6 | use Oxbow\Services\SocialAuthService; | 11 | use Oxbow\Services\SocialAuthService; |
| 7 | use Oxbow\User; | 12 | use Oxbow\User; |
| 8 | use Validator; | 13 | use Validator; |
| ... | @@ -30,15 +35,22 @@ class AuthController extends Controller | ... | @@ -30,15 +35,22 @@ class AuthController extends Controller |
| 30 | protected $redirectAfterLogout = '/login'; | 35 | protected $redirectAfterLogout = '/login'; |
| 31 | 36 | ||
| 32 | protected $socialAuthService; | 37 | protected $socialAuthService; |
| 38 | + protected $emailConfirmationService; | ||
| 39 | + protected $userRepo; | ||
| 33 | 40 | ||
| 34 | /** | 41 | /** |
| 35 | * Create a new authentication controller instance. | 42 | * Create a new authentication controller instance. |
| 36 | - * @param SocialAuthService $socialAuthService | 43 | + * @param SocialAuthService $socialAuthService |
| 44 | + * @param EmailConfirmationService $emailConfirmationService | ||
| 45 | + * @param UserRepo $userRepo | ||
| 37 | */ | 46 | */ |
| 38 | - public function __construct(SocialAuthService $socialAuthService) | 47 | + public function __construct(SocialAuthService $socialAuthService, EmailConfirmationService $emailConfirmationService, UserRepo $userRepo) |
| 39 | { | 48 | { |
| 40 | $this->middleware('guest', ['only' => ['getLogin', 'postLogin', 'getRegister']]); | 49 | $this->middleware('guest', ['only' => ['getLogin', 'postLogin', 'getRegister']]); |
| 41 | $this->socialAuthService = $socialAuthService; | 50 | $this->socialAuthService = $socialAuthService; |
| 51 | + $this->emailConfirmationService = $emailConfirmationService; | ||
| 52 | + $this->userRepo = $userRepo; | ||
| 53 | + parent::__construct(); | ||
| 42 | } | 54 | } |
| 43 | 55 | ||
| 44 | /** | 56 | /** |
| ... | @@ -52,7 +64,7 @@ class AuthController extends Controller | ... | @@ -52,7 +64,7 @@ class AuthController extends Controller |
| 52 | return Validator::make($data, [ | 64 | return Validator::make($data, [ |
| 53 | 'name' => 'required|max:255', | 65 | 'name' => 'required|max:255', |
| 54 | 'email' => 'required|email|max:255|unique:users', | 66 | 'email' => 'required|email|max:255|unique:users', |
| 55 | - 'password' => 'required|confirmed|min:6', | 67 | + 'password' => 'required|min:6', |
| 56 | ]); | 68 | ]); |
| 57 | } | 69 | } |
| 58 | 70 | ||
| ... | @@ -71,6 +83,13 @@ class AuthController extends Controller | ... | @@ -71,6 +83,13 @@ class AuthController extends Controller |
| 71 | ]); | 83 | ]); |
| 72 | } | 84 | } |
| 73 | 85 | ||
| 86 | + protected function checkRegistrationAllowed() | ||
| 87 | + { | ||
| 88 | + if(!\Setting::get('registration-enabled')) { | ||
| 89 | + throw new UserRegistrationException('Registrations are currently disabled.', '/login'); | ||
| 90 | + } | ||
| 91 | + } | ||
| 92 | + | ||
| 74 | /** | 93 | /** |
| 75 | * Show the application registration form. | 94 | * Show the application registration form. |
| 76 | * | 95 | * |
| ... | @@ -78,11 +97,105 @@ class AuthController extends Controller | ... | @@ -78,11 +97,105 @@ class AuthController extends Controller |
| 78 | */ | 97 | */ |
| 79 | public function getRegister() | 98 | public function getRegister() |
| 80 | { | 99 | { |
| 100 | + $this->checkRegistrationAllowed(); | ||
| 81 | $socialDrivers = $this->socialAuthService->getActiveDrivers(); | 101 | $socialDrivers = $this->socialAuthService->getActiveDrivers(); |
| 82 | return view('auth.register', ['socialDrivers' => $socialDrivers]); | 102 | return view('auth.register', ['socialDrivers' => $socialDrivers]); |
| 83 | } | 103 | } |
| 84 | 104 | ||
| 85 | /** | 105 | /** |
| 106 | + * Handle a registration request for the application. | ||
| 107 | + * | ||
| 108 | + * @param \Illuminate\Http\Request $request | ||
| 109 | + * @return \Illuminate\Http\Response | ||
| 110 | + * @throws UserRegistrationException | ||
| 111 | + */ | ||
| 112 | + public function postRegister(Request $request) | ||
| 113 | + { | ||
| 114 | + $this->checkRegistrationAllowed(); | ||
| 115 | + $validator = $this->validator($request->all()); | ||
| 116 | + | ||
| 117 | + if ($validator->fails()) { | ||
| 118 | + $this->throwValidationException( | ||
| 119 | + $request, $validator | ||
| 120 | + ); | ||
| 121 | + } | ||
| 122 | + | ||
| 123 | + if(\Setting::get('registration-restrict')) { | ||
| 124 | + $restrictedEmailDomains = explode(',', str_replace(' ', '', \Setting::get('registration-restrict'))); | ||
| 125 | + $userEmailDomain = $domain = substr(strrchr($request->get('email'), "@"), 1); | ||
| 126 | + if(!in_array($userEmailDomain, $restrictedEmailDomains)) { | ||
| 127 | + throw new UserRegistrationException('That email domain does not have access to this application', '/register'); | ||
| 128 | + } | ||
| 129 | + } | ||
| 130 | + | ||
| 131 | + $newUser = $this->create($request->all()); | ||
| 132 | + $newUser->attachRoleId(\Setting::get('registration-role'), 1); | ||
| 133 | + | ||
| 134 | + if(\Setting::get('registration-confirmation') || \Setting::get('registration-restrict')) { | ||
| 135 | + $newUser->email_confirmed = false; | ||
| 136 | + $newUser->save(); | ||
| 137 | + $this->emailConfirmationService->sendConfirmation($newUser); | ||
| 138 | + return redirect('/register/confirm'); | ||
| 139 | + } | ||
| 140 | + | ||
| 141 | + auth()->login($newUser); | ||
| 142 | + return redirect($this->redirectPath()); | ||
| 143 | + } | ||
| 144 | + | ||
| 145 | + /** | ||
| 146 | + * Show the page to tell the user to check thier email | ||
| 147 | + * and confirm their address. | ||
| 148 | + */ | ||
| 149 | + public function getRegisterConfirmation() | ||
| 150 | + { | ||
| 151 | + return view('auth/register-confirm'); | ||
| 152 | + } | ||
| 153 | + | ||
| 154 | + /** | ||
| 155 | + * Confirms an email via a token and logs the user into the system. | ||
| 156 | + * @param $token | ||
| 157 | + * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector | ||
| 158 | + * @throws UserRegistrationException | ||
| 159 | + */ | ||
| 160 | + public function confirmEmail($token) | ||
| 161 | + { | ||
| 162 | + $confirmation = $this->emailConfirmationService->getEmailConfirmationFromToken($token); | ||
| 163 | + $user = $confirmation->user; | ||
| 164 | + $user->email_confirmed = true; | ||
| 165 | + $user->save(); | ||
| 166 | + auth()->login($confirmation->user); | ||
| 167 | + session()->flash('success', 'Your email has been confirmed!'); | ||
| 168 | + $this->emailConfirmationService->deleteConfirmationsByUser($user); | ||
| 169 | + return redirect($this->redirectPath); | ||
| 170 | + } | ||
| 171 | + | ||
| 172 | + /** | ||
| 173 | + * Shows a notice that a user's email address has not been confirmed, | ||
| 174 | + * Also has the option to re-send the confirmation email. | ||
| 175 | + * @return \Illuminate\View\View | ||
| 176 | + */ | ||
| 177 | + public function showAwaitingConfirmation() | ||
| 178 | + { | ||
| 179 | + return view('auth/user-unconfirmed'); | ||
| 180 | + } | ||
| 181 | + | ||
| 182 | + /** | ||
| 183 | + * Resend the confirmation email | ||
| 184 | + * @param Request $request | ||
| 185 | + * @return \Illuminate\View\View | ||
| 186 | + */ | ||
| 187 | + public function resendConfirmation(Request $request) | ||
| 188 | + { | ||
| 189 | + $this->validate($request, [ | ||
| 190 | + 'email' => 'required|email|exists:users,email' | ||
| 191 | + ]); | ||
| 192 | + $user = $this->userRepo->getByEmail($request->get('email')); | ||
| 193 | + $this->emailConfirmationService->sendConfirmation($user); | ||
| 194 | + \Session::flash('success', 'Confirmation email resent, Please check your inbox.'); | ||
| 195 | + return redirect('/register/confirm'); | ||
| 196 | + } | ||
| 197 | + | ||
| 198 | + /** | ||
| 86 | * Show the application login form. | 199 | * Show the application login form. |
| 87 | * | 200 | * |
| 88 | * @return \Illuminate\Http\Response | 201 | * @return \Illuminate\Http\Response | ... | ... |
| ... | @@ -38,6 +38,7 @@ class SettingController extends Controller | ... | @@ -38,6 +38,7 @@ class SettingController extends Controller |
| 38 | $key = str_replace('setting-', '', trim($name)); | 38 | $key = str_replace('setting-', '', trim($name)); |
| 39 | Setting::put($key, $value); | 39 | Setting::put($key, $value); |
| 40 | } | 40 | } |
| 41 | + session()->flash('success', 'Settings Saved'); | ||
| 41 | return redirect('/settings'); | 42 | return redirect('/settings'); |
| 42 | } | 43 | } |
| 43 | 44 | ... | ... |
| ... | @@ -118,7 +118,6 @@ class UserController extends Controller | ... | @@ -118,7 +118,6 @@ class UserController extends Controller |
| 118 | } | 118 | } |
| 119 | 119 | ||
| 120 | if ($request->has('password') && $request->get('password') != '') { | 120 | if ($request->has('password') && $request->get('password') != '') { |
| 121 | - //dd('cat'); | ||
| 122 | $password = $request->get('password'); | 121 | $password = $request->get('password'); |
| 123 | $user->password = bcrypt($password); | 122 | $user->password = bcrypt($password); |
| 124 | } | 123 | } | ... | ... |
| ... | @@ -4,6 +4,7 @@ namespace Oxbow\Http\Middleware; | ... | @@ -4,6 +4,7 @@ namespace Oxbow\Http\Middleware; |
| 4 | 4 | ||
| 5 | use Closure; | 5 | use Closure; |
| 6 | use Illuminate\Contracts\Auth\Guard; | 6 | use Illuminate\Contracts\Auth\Guard; |
| 7 | +use Oxbow\Exceptions\UserRegistrationException; | ||
| 7 | use Setting; | 8 | use Setting; |
| 8 | 9 | ||
| 9 | class Authenticate | 10 | class Authenticate |
| ... | @@ -34,6 +35,9 @@ class Authenticate | ... | @@ -34,6 +35,9 @@ class Authenticate |
| 34 | */ | 35 | */ |
| 35 | public function handle($request, Closure $next) | 36 | public function handle($request, Closure $next) |
| 36 | { | 37 | { |
| 38 | + if(auth()->check() && auth()->user()->email_confirmed == false) { | ||
| 39 | + return redirect()->guest('/register/confirm/awaiting'); | ||
| 40 | + } | ||
| 37 | if ($this->auth->guest() && !Setting::get('app-public')) { | 41 | if ($this->auth->guest() && !Setting::get('app-public')) { |
| 38 | if ($request->ajax()) { | 42 | if ($request->ajax()) { |
| 39 | return response('Unauthorized.', 401); | 43 | return response('Unauthorized.', 401); | ... | ... |
| ... | @@ -88,6 +88,11 @@ Route::get('/login', 'Auth\AuthController@getLogin'); | ... | @@ -88,6 +88,11 @@ Route::get('/login', 'Auth\AuthController@getLogin'); |
| 88 | Route::post('/login', 'Auth\AuthController@postLogin'); | 88 | Route::post('/login', 'Auth\AuthController@postLogin'); |
| 89 | Route::get('/logout', 'Auth\AuthController@getLogout'); | 89 | Route::get('/logout', 'Auth\AuthController@getLogout'); |
| 90 | Route::get('/register', 'Auth\AuthController@getRegister'); | 90 | Route::get('/register', 'Auth\AuthController@getRegister'); |
| 91 | +Route::get('/register/confirm', 'Auth\AuthController@getRegisterConfirmation'); | ||
| 92 | +Route::get('/register/confirm/awaiting', 'Auth\AuthController@showAwaitingConfirmation'); | ||
| 93 | +Route::post('/register/confirm/resend', 'Auth\AuthController@resendConfirmation'); | ||
| 94 | +Route::get('/register/confirm/{token}', 'Auth\AuthController@confirmEmail'); | ||
| 95 | +Route::post('/register', 'Auth\AuthController@postRegister'); | ||
| 91 | 96 | ||
| 92 | // Password reset link request routes... | 97 | // Password reset link request routes... |
| 93 | Route::get('/password/email', 'Auth\PasswordController@getEmail'); | 98 | Route::get('/password/email', 'Auth\PasswordController@getEmail'); | ... | ... |
| ... | @@ -21,4 +21,9 @@ class UserRepo | ... | @@ -21,4 +21,9 @@ class UserRepo |
| 21 | public function getByEmail($email) { | 21 | public function getByEmail($email) { |
| 22 | return $this->user->where('email', '=', $email)->first(); | 22 | return $this->user->where('email', '=', $email)->first(); |
| 23 | } | 23 | } |
| 24 | + | ||
| 25 | + public function getById($id) | ||
| 26 | + { | ||
| 27 | + return $this->user->findOrFail($id); | ||
| 28 | + } | ||
| 24 | } | 29 | } |
| ... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
app/Services/EmailConfirmationService.php
0 → 100644
| 1 | +<?php namespace Oxbow\Services; | ||
| 2 | + | ||
| 3 | + | ||
| 4 | +use Carbon\Carbon; | ||
| 5 | +use Illuminate\Contracts\Mail\Mailer; | ||
| 6 | +use Illuminate\Mail\Message; | ||
| 7 | +use Oxbow\EmailConfirmation; | ||
| 8 | +use Oxbow\Exceptions\ConfirmationEmailException; | ||
| 9 | +use Oxbow\Exceptions\UserRegistrationException; | ||
| 10 | +use Oxbow\Repos\UserRepo; | ||
| 11 | +use Oxbow\Setting; | ||
| 12 | +use Oxbow\User; | ||
| 13 | + | ||
| 14 | +class EmailConfirmationService | ||
| 15 | +{ | ||
| 16 | + protected $mailer; | ||
| 17 | + protected $emailConfirmation; | ||
| 18 | + | ||
| 19 | + /** | ||
| 20 | + * EmailConfirmationService constructor. | ||
| 21 | + * @param Mailer $mailer | ||
| 22 | + * @param EmailConfirmation $emailConfirmation | ||
| 23 | + */ | ||
| 24 | + public function __construct(Mailer $mailer, EmailConfirmation $emailConfirmation) | ||
| 25 | + { | ||
| 26 | + $this->mailer = $mailer; | ||
| 27 | + $this->emailConfirmation = $emailConfirmation; | ||
| 28 | + } | ||
| 29 | + | ||
| 30 | + /** | ||
| 31 | + * Create new confirmation for a user, | ||
| 32 | + * Also removes any existing old ones. | ||
| 33 | + * @param User $user | ||
| 34 | + * @throws ConfirmationEmailException | ||
| 35 | + */ | ||
| 36 | + public function sendConfirmation(User $user) | ||
| 37 | + { | ||
| 38 | + if($user->email_confirmed) { | ||
| 39 | + throw new ConfirmationEmailException('Email has already been confirmed, Try logging in.', '/login'); | ||
| 40 | + } | ||
| 41 | + $this->deleteConfirmationsByUser($user); | ||
| 42 | + $token = $this->getToken(); | ||
| 43 | + $this->emailConfirmation->create([ | ||
| 44 | + 'user_id' => $user->id, | ||
| 45 | + 'token' => $token, | ||
| 46 | + ]); | ||
| 47 | + $this->mailer->send('emails/email-confirmation', ['token' => $token], function (Message $message) use ($user) { | ||
| 48 | + $appName = \Setting::get('app-name', 'BookStack'); | ||
| 49 | + $message->to($user->email, $user->name)->subject('Confirm your email on ' . $appName . '.'); | ||
| 50 | + }); | ||
| 51 | + } | ||
| 52 | + | ||
| 53 | + /** | ||
| 54 | + * Gets an email confirmation by looking up the token, | ||
| 55 | + * Ensures the token has not expired. | ||
| 56 | + * @param string $token | ||
| 57 | + * @return EmailConfirmation | ||
| 58 | + * @throws UserRegistrationException | ||
| 59 | + */ | ||
| 60 | + public function getEmailConfirmationFromToken($token) | ||
| 61 | + { | ||
| 62 | + $emailConfirmation = $this->emailConfirmation->where('token', '=', $token)->first(); | ||
| 63 | + // If not found | ||
| 64 | + if ($emailConfirmation === null) { | ||
| 65 | + throw new UserRegistrationException('This confirmation token is not valid or has already been used, Please try registering again.', '/register'); | ||
| 66 | + } | ||
| 67 | + | ||
| 68 | + // If more than a day old | ||
| 69 | + if(Carbon::now()->subDay()->gt($emailConfirmation->created_at)) { | ||
| 70 | + $this->sendConfirmation($emailConfirmation->user); | ||
| 71 | + throw new UserRegistrationException('The confirmation token has expired, A new confirmation email has been sent.', '/register/confirm'); | ||
| 72 | + } | ||
| 73 | + | ||
| 74 | + return $emailConfirmation; | ||
| 75 | + } | ||
| 76 | + | ||
| 77 | + | ||
| 78 | + /** | ||
| 79 | + * Delete all email confirmations that belong to a user. | ||
| 80 | + * @param User $user | ||
| 81 | + * @return mixed | ||
| 82 | + */ | ||
| 83 | + public function deleteConfirmationsByUser(User $user) | ||
| 84 | + { | ||
| 85 | + return $this->emailConfirmation->where('user_id', '=', $user->id)->delete(); | ||
| 86 | + } | ||
| 87 | + | ||
| 88 | + /** | ||
| 89 | + * Creates a unique token within the email confirmation database. | ||
| 90 | + * @return string | ||
| 91 | + */ | ||
| 92 | + protected function getToken() | ||
| 93 | + { | ||
| 94 | + $token = str_random(24); | ||
| 95 | + while ($this->emailConfirmation->where('token', '=', $token)->exists()) { | ||
| 96 | + $token = str_random(25); | ||
| 97 | + } | ||
| 98 | + return $token; | ||
| 99 | + } | ||
| 100 | + | ||
| 101 | + | ||
| 102 | +} | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file |
| ... | @@ -14,8 +14,8 @@ class CreateSocialAccountsTable extends Migration | ... | @@ -14,8 +14,8 @@ class CreateSocialAccountsTable extends Migration |
| 14 | { | 14 | { |
| 15 | Schema::create('social_accounts', function (Blueprint $table) { | 15 | Schema::create('social_accounts', function (Blueprint $table) { |
| 16 | $table->increments('id'); | 16 | $table->increments('id'); |
| 17 | - $table->integer('user_id')->indexed(); | 17 | + $table->integer('user_id')->index(); |
| 18 | - $table->string('driver')->indexed(); | 18 | + $table->string('driver')->index(); |
| 19 | $table->string('driver_id'); | 19 | $table->string('driver_id'); |
| 20 | $table->string('avatar'); | 20 | $table->string('avatar'); |
| 21 | $table->timestamps(); | 21 | $table->timestamps(); | ... | ... |
| 1 | +<?php | ||
| 2 | + | ||
| 3 | +use Illuminate\Database\Schema\Blueprint; | ||
| 4 | +use Illuminate\Database\Migrations\Migration; | ||
| 5 | + | ||
| 6 | +class AddEmailConfirmationTable extends Migration | ||
| 7 | +{ | ||
| 8 | + /** | ||
| 9 | + * Run the migrations. | ||
| 10 | + * | ||
| 11 | + * @return void | ||
| 12 | + */ | ||
| 13 | + public function up() | ||
| 14 | + { | ||
| 15 | + Schema::table('users', function (Blueprint $table) { | ||
| 16 | + $table->boolean('email_confirmed')->default(true); | ||
| 17 | + }); | ||
| 18 | + | ||
| 19 | + Schema::create('email_confirmations', function (Blueprint $table) { | ||
| 20 | + $table->increments('id'); | ||
| 21 | + $table->integer('user_id')->index(); | ||
| 22 | + $table->string('token')->index(); | ||
| 23 | + $table->timestamps(); | ||
| 24 | + }); | ||
| 25 | + } | ||
| 26 | + | ||
| 27 | + /** | ||
| 28 | + * Reverse the migrations. | ||
| 29 | + * | ||
| 30 | + * @return void | ||
| 31 | + */ | ||
| 32 | + public function down() | ||
| 33 | + { | ||
| 34 | + Schema::table('users', function (Blueprint $table) { | ||
| 35 | + $table->dropColumn('email_confirmed'); | ||
| 36 | + }); | ||
| 37 | + Schema::drop('email_confirmations'); | ||
| 38 | + } | ||
| 39 | +} |
| 1 | +@extends('public') | ||
| 2 | + | ||
| 3 | +@section('header-buttons') | ||
| 4 | + @if(!$signedIn) | ||
| 5 | + <a href="/login"><i class="zmdi zmdi-sign-in"></i>Sign in</a> | ||
| 6 | + @endif | ||
| 7 | +@stop | ||
| 8 | + | ||
| 9 | +@section('content') | ||
| 10 | + | ||
| 11 | + <div class="text-center"> | ||
| 12 | + <div class="center-box"> | ||
| 13 | + <h2>Thanks for registering!</h2> | ||
| 14 | + <p>Please check your email and click the confirmation button to access {{ \Setting::get('app-name') }}.</p> | ||
| 15 | + </div> | ||
| 16 | + </div> | ||
| 17 | + | ||
| 18 | + | ||
| 19 | +@stop |
| ... | @@ -8,9 +8,9 @@ | ... | @@ -8,9 +8,9 @@ |
| 8 | 8 | ||
| 9 | <div class="text-center"> | 9 | <div class="text-center"> |
| 10 | <div class="center-box"> | 10 | <div class="center-box"> |
| 11 | - <h1>Register</h1> | 11 | + <h1>Sign Up</h1> |
| 12 | 12 | ||
| 13 | - <form action="/login" method="POST"> | 13 | + <form action="/register" method="POST"> |
| 14 | {!! csrf_field() !!} | 14 | {!! csrf_field() !!} |
| 15 | 15 | ||
| 16 | <div class="form-group"> | 16 | <div class="form-group"> |
| ... | @@ -29,13 +29,14 @@ | ... | @@ -29,13 +29,14 @@ |
| 29 | </div> | 29 | </div> |
| 30 | 30 | ||
| 31 | <div class="from-group"> | 31 | <div class="from-group"> |
| 32 | - <button class="button block pos">Sign In</button> | 32 | + <button class="button block pos">Create Account</button> |
| 33 | </div> | 33 | </div> |
| 34 | </form> | 34 | </form> |
| 35 | 35 | ||
| 36 | @if(count($socialDrivers) > 0) | 36 | @if(count($socialDrivers) > 0) |
| 37 | <hr class="margin-top"> | 37 | <hr class="margin-top"> |
| 38 | <h3 class="text-muted">Social Registration</h3> | 38 | <h3 class="text-muted">Social Registration</h3> |
| 39 | + <p class="text-small">Register and sign in using another service.</p> | ||
| 39 | @if(isset($socialDrivers['google'])) | 40 | @if(isset($socialDrivers['google'])) |
| 40 | <a href="/register/service/google" style="color: #DC4E41;"><i class="zmdi zmdi-google-plus-box zmdi-hc-4x"></i></a> | 41 | <a href="/register/service/google" style="color: #DC4E41;"><i class="zmdi zmdi-google-plus-box zmdi-hc-4x"></i></a> |
| 41 | @endif | 42 | @endif | ... | ... |
| 1 | +@extends('public') | ||
| 2 | + | ||
| 3 | +@section('content') | ||
| 4 | + | ||
| 5 | + <div class="row"> | ||
| 6 | + <div class="col-md-6 col-md-offset-3"> | ||
| 7 | + <h2>Email Address not confirmed</h2> | ||
| 8 | + <p class="text-muted">Your email address has not yet been confirmed. <br> | ||
| 9 | + Please click the link in the email that was sent shortly after you registered. <br> | ||
| 10 | + If you cannot find the email you can re-send the confirmation email by submitting the form below. | ||
| 11 | + </p> | ||
| 12 | + <hr> | ||
| 13 | + <form action="/register/confirm/resend" method="POST"> | ||
| 14 | + {!! csrf_field() !!} | ||
| 15 | + <div class="form-group"> | ||
| 16 | + <label for="email">Email Address</label> | ||
| 17 | + @if(auth()->check()) | ||
| 18 | + @include('form/text', ['name' => 'email', 'model' => auth()->user()]) | ||
| 19 | + @else | ||
| 20 | + @include('form/text', ['name' => 'email']) | ||
| 21 | + @endif | ||
| 22 | + </div> | ||
| 23 | + <div class="form-group"> | ||
| 24 | + <button type="submit" class="button pos">Resend Confirmation Email</button> | ||
| 25 | + </div> | ||
| 26 | + </form> | ||
| 27 | + </div> | ||
| 28 | + </div> | ||
| 29 | + | ||
| 30 | +@stop |
| ... | @@ -157,7 +157,7 @@ | ... | @@ -157,7 +157,7 @@ |
| 157 | <table style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;font-family:'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif;font-size:100%;line-height:1.6;width:100%;"> | 157 | <table style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;font-family:'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif;font-size:100%;line-height:1.6;width:100%;"> |
| 158 | <tr style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;font-family:'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif;font-size:100%;line-height:1.6;"> | 158 | <tr style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;font-family:'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif;font-size:100%;line-height:1.6;"> |
| 159 | <td class="padding" style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;font-family:'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif;font-size:100%;line-height:1.6;padding-top:10px;padding-bottom:10px;padding-right:0;padding-left:0;"> | 159 | <td class="padding" style="margin-top:0;margin-bottom:0;margin-right:0;margin-left:0;font-family:'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif;font-size:100%;line-height:1.6;padding-top:10px;padding-bottom:10px;padding-right:0;padding-left:0;"> |
| 160 | - <p style="margin-top:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;font-family:'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif;line-height:1.6;margin-bottom:10px;font-weight:normal;font-size:14px;color:#888888;"><a class="btn-primary" href="{{ url('user/confirm/'.$token) }}" style="margin-top:0;margin-bottom:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;font-family:'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif;font-size:100%;text-decoration:none;color:#FFF;background-color:#348eda;border-style:solid;border-color:#348eda;border-width:10px 20px;line-height:2;font-weight:bold;margin-right:10px;text-align:center;cursor:pointer;display:inline-block;border-radius:4px;">Confirm Email</a></p> | 160 | + <p style="margin-top:0;margin-right:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;font-family:'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif;line-height:1.6;margin-bottom:10px;font-weight:normal;font-size:14px;color:#888888;"><a class="btn-primary" href="{{ url('/register/confirm/'.$token) }}" style="margin-top:0;margin-bottom:0;margin-left:0;padding-top:0;padding-bottom:0;padding-right:0;padding-left:0;font-family:'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif;font-size:100%;text-decoration:none;color:#FFF;background-color:#348eda;border-style:solid;border-color:#348eda;border-width:10px 20px;line-height:2;font-weight:bold;margin-right:10px;text-align:center;cursor:pointer;display:inline-block;border-radius:4px;">Confirm Email</a></p> |
| 161 | </td> | 161 | </td> |
| 162 | </tr> | 162 | </tr> |
| 163 | </table> | 163 | </table> | ... | ... |
| ... | @@ -37,6 +37,19 @@ | ... | @@ -37,6 +37,19 @@ |
| 37 | <div class="links text-center"> | 37 | <div class="links text-center"> |
| 38 | @yield('header-buttons') | 38 | @yield('header-buttons') |
| 39 | </div> | 39 | </div> |
| 40 | + @if($signedIn) | ||
| 41 | + <img class="avatar" src="{{$currentUser->getAvatar(30)}}" alt="{{ $currentUser->name }}"> | ||
| 42 | + <div class="dropdown-container" data-dropdown> | ||
| 43 | + <span class="user-name" data-dropdown-toggle> | ||
| 44 | + {{ $currentUser->name }} <i class="zmdi zmdi-caret-down"></i> | ||
| 45 | + </span> | ||
| 46 | + <ul> | ||
| 47 | + <li> | ||
| 48 | + <a href="/logout" class="text-neg"><i class="zmdi zmdi-run zmdi-hc-lg"></i>Logout</a> | ||
| 49 | + </li> | ||
| 50 | + </ul> | ||
| 51 | + </div> | ||
| 52 | + @endif | ||
| 40 | </div> | 53 | </div> |
| 41 | </div> | 54 | </div> |
| 42 | </div> | 55 | </div> | ... | ... |
-
Please register or sign in to post a comment