diff --git a/app/EmailConfirmation.php b/app/EmailConfirmation.php
new file mode 100644
index 000000000..a8f8f80b8
--- /dev/null
+++ b/app/EmailConfirmation.php
@@ -0,0 +1,15 @@
+<?php
+
+namespace Oxbow;
+
+use Illuminate\Database\Eloquent\Model;
+
+class EmailConfirmation extends Model
+{
+    protected $fillable = ['user_id', 'token'];
+
+    public function user()
+    {
+        return $this->belongsTo('Oxbow\User');
+    }
+}
diff --git a/app/Exceptions/ConfirmationEmailException.php b/app/Exceptions/ConfirmationEmailException.php
new file mode 100644
index 000000000..570eed2e9
--- /dev/null
+++ b/app/Exceptions/ConfirmationEmailException.php
@@ -0,0 +1,7 @@
+<?php namespace Oxbow\Exceptions;
+
+
+class ConfirmationEmailException extends NotifyException
+{
+
+}
\ No newline at end of file
diff --git a/app/Exceptions/UserRegistrationException.php b/app/Exceptions/UserRegistrationException.php
new file mode 100644
index 000000000..1c673a110
--- /dev/null
+++ b/app/Exceptions/UserRegistrationException.php
@@ -0,0 +1,7 @@
+<?php namespace Oxbow\Exceptions;
+
+
+class UserRegistrationException extends NotifyException
+{
+
+}
\ No newline at end of file
diff --git a/app/Http/Controllers/Auth/AuthController.php b/app/Http/Controllers/Auth/AuthController.php
index f290aeabb..0d4f6b844 100644
--- a/app/Http/Controllers/Auth/AuthController.php
+++ b/app/Http/Controllers/Auth/AuthController.php
@@ -2,7 +2,12 @@
 
 namespace Oxbow\Http\Controllers\Auth;
 
+use Illuminate\Http\Request;
 use Oxbow\Exceptions\SocialSignInException;
+use Oxbow\Exceptions\UserRegistrationException;
+use Oxbow\Repos\UserRepo;
+use Oxbow\Services\EmailConfirmationService;
+use Oxbow\Services\Facades\Setting;
 use Oxbow\Services\SocialAuthService;
 use Oxbow\User;
 use Validator;
@@ -30,15 +35,22 @@ class AuthController extends Controller
     protected $redirectAfterLogout = '/login';
 
     protected $socialAuthService;
+    protected $emailConfirmationService;
+    protected $userRepo;
 
     /**
      * Create a new authentication controller instance.
-     * @param SocialAuthService $socialAuthService
+     * @param SocialAuthService        $socialAuthService
+     * @param EmailConfirmationService $emailConfirmationService
+     * @param UserRepo                 $userRepo
      */
-    public function __construct(SocialAuthService $socialAuthService)
+    public function __construct(SocialAuthService $socialAuthService, EmailConfirmationService $emailConfirmationService, UserRepo $userRepo)
     {
         $this->middleware('guest', ['only' => ['getLogin', 'postLogin', 'getRegister']]);
         $this->socialAuthService = $socialAuthService;
+        $this->emailConfirmationService = $emailConfirmationService;
+        $this->userRepo = $userRepo;
+        parent::__construct();
     }
 
     /**
@@ -52,7 +64,7 @@ class AuthController extends Controller
         return Validator::make($data, [
             'name'     => 'required|max:255',
             'email'    => 'required|email|max:255|unique:users',
-            'password' => 'required|confirmed|min:6',
+            'password' => 'required|min:6',
         ]);
     }
 
@@ -71,6 +83,13 @@ class AuthController extends Controller
         ]);
     }
 
+    protected function checkRegistrationAllowed()
+    {
+        if(!\Setting::get('registration-enabled')) {
+            throw new UserRegistrationException('Registrations are currently disabled.', '/login');
+        }
+    }
+
     /**
      * Show the application registration form.
      *
@@ -78,10 +97,104 @@ class AuthController extends Controller
      */
     public function getRegister()
     {
+        $this->checkRegistrationAllowed();
         $socialDrivers = $this->socialAuthService->getActiveDrivers();
         return view('auth.register', ['socialDrivers' => $socialDrivers]);
     }
 
+    /**
+     * Handle a registration request for the application.
+     *
+     * @param  \Illuminate\Http\Request $request
+     * @return \Illuminate\Http\Response
+     * @throws UserRegistrationException
+     */
+    public function postRegister(Request $request)
+    {
+        $this->checkRegistrationAllowed();
+        $validator = $this->validator($request->all());
+
+        if ($validator->fails()) {
+            $this->throwValidationException(
+                $request, $validator
+            );
+        }
+
+        if(\Setting::get('registration-restrict')) {
+            $restrictedEmailDomains = explode(',', str_replace(' ', '', \Setting::get('registration-restrict')));
+            $userEmailDomain = $domain = substr(strrchr($request->get('email'), "@"), 1);
+            if(!in_array($userEmailDomain, $restrictedEmailDomains)) {
+                throw new UserRegistrationException('That email domain does not have access to this application', '/register');
+            }
+        }
+
+        $newUser = $this->create($request->all());
+        $newUser->attachRoleId(\Setting::get('registration-role'), 1);
+
+        if(\Setting::get('registration-confirmation') || \Setting::get('registration-restrict')) {
+            $newUser->email_confirmed = false;
+            $newUser->save();
+            $this->emailConfirmationService->sendConfirmation($newUser);
+            return redirect('/register/confirm');
+        }
+
+        auth()->login($newUser);
+        return redirect($this->redirectPath());
+    }
+
+    /**
+     * Show the page to tell the user to check thier email
+     * and confirm their address.
+     */
+    public function getRegisterConfirmation()
+    {
+        return view('auth/register-confirm');
+    }
+
+    /**
+     * Confirms an email via a token and logs the user into the system.
+     * @param $token
+     * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
+     * @throws UserRegistrationException
+     */
+    public function confirmEmail($token)
+    {
+        $confirmation = $this->emailConfirmationService->getEmailConfirmationFromToken($token);
+        $user = $confirmation->user;
+        $user->email_confirmed = true;
+        $user->save();
+        auth()->login($confirmation->user);
+        session()->flash('success', 'Your email has been confirmed!');
+        $this->emailConfirmationService->deleteConfirmationsByUser($user);
+        return redirect($this->redirectPath);
+    }
+
+    /**
+     * Shows a notice that a user's email address has not been confirmed,
+     * Also has the option to re-send the confirmation email.
+     * @return \Illuminate\View\View
+     */
+    public function showAwaitingConfirmation()
+    {
+        return view('auth/user-unconfirmed');
+    }
+
+    /**
+     * Resend the confirmation email
+     * @param Request $request
+     * @return \Illuminate\View\View
+     */
+    public function resendConfirmation(Request $request)
+    {
+        $this->validate($request, [
+            'email' => 'required|email|exists:users,email'
+        ]);
+        $user = $this->userRepo->getByEmail($request->get('email'));
+        $this->emailConfirmationService->sendConfirmation($user);
+        \Session::flash('success', 'Confirmation email resent, Please check your inbox.');
+        return redirect('/register/confirm');
+    }
+
     /**
      * Show the application login form.
      *
diff --git a/app/Http/Controllers/SettingController.php b/app/Http/Controllers/SettingController.php
index e0695f22d..5193a9d3b 100644
--- a/app/Http/Controllers/SettingController.php
+++ b/app/Http/Controllers/SettingController.php
@@ -38,6 +38,7 @@ class SettingController extends Controller
             $key = str_replace('setting-', '', trim($name));
             Setting::put($key, $value);
         }
+        session()->flash('success', 'Settings Saved');
         return redirect('/settings');
     }
 
diff --git a/app/Http/Controllers/UserController.php b/app/Http/Controllers/UserController.php
index f6a8d13e3..9923e9d9c 100644
--- a/app/Http/Controllers/UserController.php
+++ b/app/Http/Controllers/UserController.php
@@ -118,7 +118,6 @@ class UserController extends Controller
         }
 
         if ($request->has('password') && $request->get('password') != '') {
-            //dd('cat');
             $password = $request->get('password');
             $user->password = bcrypt($password);
         }
diff --git a/app/Http/Middleware/Authenticate.php b/app/Http/Middleware/Authenticate.php
index f0b2f7eda..f3c6f5925 100644
--- a/app/Http/Middleware/Authenticate.php
+++ b/app/Http/Middleware/Authenticate.php
@@ -4,6 +4,7 @@ namespace Oxbow\Http\Middleware;
 
 use Closure;
 use Illuminate\Contracts\Auth\Guard;
+use Oxbow\Exceptions\UserRegistrationException;
 use Setting;
 
 class Authenticate
@@ -34,6 +35,9 @@ class Authenticate
      */
     public function handle($request, Closure $next)
     {
+        if(auth()->check() && auth()->user()->email_confirmed == false) {
+            return redirect()->guest('/register/confirm/awaiting');
+        }
         if ($this->auth->guest() && !Setting::get('app-public')) {
             if ($request->ajax()) {
                 return response('Unauthorized.', 401);
diff --git a/app/Http/routes.php b/app/Http/routes.php
index be7ac8736..df2860ea5 100644
--- a/app/Http/routes.php
+++ b/app/Http/routes.php
@@ -88,6 +88,11 @@ Route::get('/login', 'Auth\AuthController@getLogin');
 Route::post('/login', 'Auth\AuthController@postLogin');
 Route::get('/logout', 'Auth\AuthController@getLogout');
 Route::get('/register', 'Auth\AuthController@getRegister');
+Route::get('/register/confirm', 'Auth\AuthController@getRegisterConfirmation');
+Route::get('/register/confirm/awaiting', 'Auth\AuthController@showAwaitingConfirmation');
+Route::post('/register/confirm/resend', 'Auth\AuthController@resendConfirmation');
+Route::get('/register/confirm/{token}', 'Auth\AuthController@confirmEmail');
+Route::post('/register', 'Auth\AuthController@postRegister');
 
 // Password reset link request routes...
 Route::get('/password/email', 'Auth\PasswordController@getEmail');
diff --git a/app/Repos/UserRepo.php b/app/Repos/UserRepo.php
index f6c80ff42..43b3cf4ca 100644
--- a/app/Repos/UserRepo.php
+++ b/app/Repos/UserRepo.php
@@ -21,4 +21,9 @@ class UserRepo
     public function getByEmail($email) {
         return $this->user->where('email', '=', $email)->first();
     }
+
+    public function getById($id)
+    {
+        return $this->user->findOrFail($id);
+    }
 }
\ No newline at end of file
diff --git a/app/Services/EmailConfirmationService.php b/app/Services/EmailConfirmationService.php
new file mode 100644
index 000000000..dd85ad834
--- /dev/null
+++ b/app/Services/EmailConfirmationService.php
@@ -0,0 +1,102 @@
+<?php namespace Oxbow\Services;
+
+
+use Carbon\Carbon;
+use Illuminate\Contracts\Mail\Mailer;
+use Illuminate\Mail\Message;
+use Oxbow\EmailConfirmation;
+use Oxbow\Exceptions\ConfirmationEmailException;
+use Oxbow\Exceptions\UserRegistrationException;
+use Oxbow\Repos\UserRepo;
+use Oxbow\Setting;
+use Oxbow\User;
+
+class EmailConfirmationService
+{
+    protected $mailer;
+    protected $emailConfirmation;
+
+    /**
+     * EmailConfirmationService constructor.
+     * @param Mailer            $mailer
+     * @param EmailConfirmation $emailConfirmation
+     */
+    public function __construct(Mailer $mailer, EmailConfirmation $emailConfirmation)
+    {
+        $this->mailer = $mailer;
+        $this->emailConfirmation = $emailConfirmation;
+    }
+
+    /**
+     * Create new confirmation for a user,
+     * Also removes any existing old ones.
+     * @param User $user
+     * @throws ConfirmationEmailException
+     */
+    public function sendConfirmation(User $user)
+    {
+        if($user->email_confirmed) {
+            throw new ConfirmationEmailException('Email has already been confirmed, Try logging in.', '/login');
+        }
+        $this->deleteConfirmationsByUser($user);
+        $token = $this->getToken();
+        $this->emailConfirmation->create([
+            'user_id' => $user->id,
+            'token'   => $token,
+        ]);
+        $this->mailer->send('emails/email-confirmation', ['token' => $token], function (Message $message) use ($user) {
+            $appName = \Setting::get('app-name', 'BookStack');
+            $message->to($user->email, $user->name)->subject('Confirm your email on ' . $appName . '.');
+        });
+    }
+
+    /**
+     * Gets an email confirmation by looking up the token,
+     * Ensures the token has not expired.
+     * @param string $token
+     * @return EmailConfirmation
+     * @throws UserRegistrationException
+     */
+    public function getEmailConfirmationFromToken($token)
+    {
+        $emailConfirmation = $this->emailConfirmation->where('token', '=', $token)->first();
+        // If not found
+        if ($emailConfirmation === null) {
+            throw new UserRegistrationException('This confirmation token is not valid or has already been used, Please try registering again.', '/register');
+        }
+
+        // If more than a day old
+        if(Carbon::now()->subDay()->gt($emailConfirmation->created_at)) {
+            $this->sendConfirmation($emailConfirmation->user);
+            throw new UserRegistrationException('The confirmation token has expired, A new confirmation email has been sent.', '/register/confirm');
+        }
+
+        return $emailConfirmation;
+    }
+
+
+    /**
+     * Delete all email confirmations that belong to a user.
+     * @param User $user
+     * @return mixed
+     */
+    public function deleteConfirmationsByUser(User $user)
+    {
+        return $this->emailConfirmation->where('user_id', '=', $user->id)->delete();
+    }
+
+    /**
+     * Creates a unique token within the email confirmation database.
+     * @return string
+     */
+    protected function getToken()
+    {
+        $token = str_random(24);
+        while ($this->emailConfirmation->where('token', '=', $token)->exists()) {
+            $token = str_random(25);
+        }
+        return $token;
+    }
+
+
+}
\ No newline at end of file
diff --git a/database/migrations/2015_09_04_165821_create_social_accounts_table.php b/database/migrations/2015_09_04_165821_create_social_accounts_table.php
index a4f627390..3933e728f 100644
--- a/database/migrations/2015_09_04_165821_create_social_accounts_table.php
+++ b/database/migrations/2015_09_04_165821_create_social_accounts_table.php
@@ -14,8 +14,8 @@ class CreateSocialAccountsTable extends Migration
     {
         Schema::create('social_accounts', function (Blueprint $table) {
             $table->increments('id');
-            $table->integer('user_id')->indexed();
-            $table->string('driver')->indexed();
+            $table->integer('user_id')->index();
+            $table->string('driver')->index();
             $table->string('driver_id');
             $table->string('avatar');
             $table->timestamps();
diff --git a/database/migrations/2015_09_05_164707_add_email_confirmation_table.php b/database/migrations/2015_09_05_164707_add_email_confirmation_table.php
new file mode 100644
index 000000000..2f20cf0cf
--- /dev/null
+++ b/database/migrations/2015_09_05_164707_add_email_confirmation_table.php
@@ -0,0 +1,39 @@
+<?php
+
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Database\Migrations\Migration;
+
+class AddEmailConfirmationTable extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::table('users', function (Blueprint $table) {
+            $table->boolean('email_confirmed')->default(true);
+        });
+
+        Schema::create('email_confirmations', function (Blueprint $table) {
+            $table->increments('id');
+            $table->integer('user_id')->index();
+            $table->string('token')->index();
+            $table->timestamps();
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::table('users', function (Blueprint $table) {
+            $table->dropColumn('email_confirmed');
+        });
+        Schema::drop('email_confirmations');
+    }
+}
diff --git a/resources/views/auth/register-confirm.blade.php b/resources/views/auth/register-confirm.blade.php
new file mode 100644
index 000000000..2f70b9ffd
--- /dev/null
+++ b/resources/views/auth/register-confirm.blade.php
@@ -0,0 +1,19 @@
+@extends('public')
+
+@section('header-buttons')
+    @if(!$signedIn)
+        <a href="/login"><i class="zmdi zmdi-sign-in"></i>Sign in</a>
+    @endif
+@stop
+
+@section('content')
+
+    <div class="text-center">
+        <div class="center-box">
+            <h2>Thanks for registering!</h2>
+            <p>Please check your email and click the confirmation button to access {{ \Setting::get('app-name') }}.</p>
+        </div>
+    </div>
+
+
+@stop
diff --git a/resources/views/auth/register.blade.php b/resources/views/auth/register.blade.php
index 48f8ebaa8..f9f5d0149 100644
--- a/resources/views/auth/register.blade.php
+++ b/resources/views/auth/register.blade.php
@@ -8,9 +8,9 @@
 
     <div class="text-center">
         <div class="center-box">
-            <h1>Register</h1>
+            <h1>Sign Up</h1>
 
-            <form action="/login" method="POST">
+            <form action="/register" method="POST">
                 {!! csrf_field() !!}
 
                 <div class="form-group">
@@ -29,13 +29,14 @@
                 </div>
 
                 <div class="from-group">
-                    <button class="button block pos">Sign In</button>
+                    <button class="button block pos">Create Account</button>
                 </div>
             </form>
 
             @if(count($socialDrivers) > 0)
                 <hr class="margin-top">
                 <h3 class="text-muted">Social Registration</h3>
+                <p class="text-small">Register and sign in using another service.</p>
                 @if(isset($socialDrivers['google']))
                     <a href="/register/service/google" style="color: #DC4E41;"><i class="zmdi zmdi-google-plus-box zmdi-hc-4x"></i></a>
                 @endif
diff --git a/resources/views/auth/user-unconfirmed.blade.php b/resources/views/auth/user-unconfirmed.blade.php
new file mode 100644
index 000000000..1b0a20a69
--- /dev/null
+++ b/resources/views/auth/user-unconfirmed.blade.php
@@ -0,0 +1,30 @@
+@extends('public')
+
+@section('content')
+
+    <div class="row">
+        <div class="col-md-6 col-md-offset-3">
+            <h2>Email Address not confirmed</h2>
+            <p class="text-muted">Your email address has not yet been confirmed. <br>
+                Please click the link in the email that was sent shortly after you registered. <br>
+                If you cannot find the email you can re-send the confirmation email by submitting the form below.
+            </p>
+            <hr>
+            <form action="/register/confirm/resend" method="POST">
+                {!! csrf_field() !!}
+                <div class="form-group">
+                    <label for="email">Email Address</label>
+                    @if(auth()->check())
+                        @include('form/text', ['name' => 'email', 'model' => auth()->user()])
+                    @else
+                        @include('form/text', ['name' => 'email'])
+                    @endif
+                </div>
+                <div class="form-group">
+                    <button type="submit" class="button pos">Resend Confirmation Email</button>
+                </div>
+            </form>
+        </div>
+    </div>
+
+@stop
diff --git a/resources/views/emails/email-confirmation.blade.php b/resources/views/emails/email-confirmation.blade.php
index f2c9710a1..b2bba96ca 100644
--- a/resources/views/emails/email-confirmation.blade.php
+++ b/resources/views/emails/email-confirmation.blade.php
@@ -157,7 +157,7 @@
                                                                      <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%;">
     <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;">
     <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;">
-    <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>
+    <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>
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 </td>
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   </tr>
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     </table>
diff --git a/resources/views/public.blade.php b/resources/views/public.blade.php
index eaff2c2d8..f252ce38c 100644
--- a/resources/views/public.blade.php
+++ b/resources/views/public.blade.php
@@ -37,6 +37,19 @@
                     <div class="links text-center">
                         @yield('header-buttons')
                     </div>
+                    @if($signedIn)
+                        <img class="avatar" src="{{$currentUser->getAvatar(30)}}" alt="{{ $currentUser->name }}">
+                        <div class="dropdown-container" data-dropdown>
+                                <span class="user-name" data-dropdown-toggle>
+                                    {{ $currentUser->name }} <i class="zmdi zmdi-caret-down"></i>
+                                </span>
+                            <ul>
+                                <li>
+                                    <a href="/logout" class="text-neg"><i class="zmdi zmdi-run zmdi-hc-lg"></i>Logout</a>
+                                </li>
+                            </ul>
+                        </div>
+                    @endif
                 </div>
             </div>
         </div>