diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..b817577
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,10 @@
+/.idea
+/vendor
+/node_modules
+package-lock.json
+composer.phar
+composer.lock
+phpunit.xml
+.phpunit.result.cache
+.DS_Store
+Thumbs.db
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..f87f5c1
--- /dev/null
+++ b/README.md
@@ -0,0 +1 @@
+# TODO
\ No newline at end of file
diff --git a/composer.json b/composer.json
new file mode 100644
index 0000000..9266a05
--- /dev/null
+++ b/composer.json
@@ -0,0 +1,31 @@
+{
+    "name": "lifeonscreen/nova-google2fa",
+    "description": "This package provides Google2FA to Laravel Nova.",
+    "keywords": [
+        "laravel",
+        "nova"
+    ],
+    "license": "MIT",
+    "require": {
+        "php": ">=7.1.0",
+        "bacon/bacon-qr-code": "^2.0",
+        "pragmarx/google2fa-laravel": "^0.2.0"
+    },
+    "autoload": {
+        "psr-4": {
+            "Lifeonscreen\\Google2fa\\": "src/"
+        }
+    },
+    "extra": {
+        "laravel": {
+            "providers": [
+                "Lifeonscreen\\Google2fa\\ToolServiceProvider"
+            ]
+        }
+    },
+    "config": {
+        "sort-packages": true
+    },
+    "minimum-stability": "dev",
+    "prefer-stable": true
+}
diff --git a/config/lifeonscreen2fa.php b/config/lifeonscreen2fa.php
new file mode 100644
index 0000000..f6c00ec
--- /dev/null
+++ b/config/lifeonscreen2fa.php
@@ -0,0 +1,10 @@
+<?php
+
+return [
+    'models' => [
+        'user' => 'App\User',
+    ],
+    'tables' => [
+        'user' => 'users',
+    ],
+];
\ No newline at end of file
diff --git a/resources/database/2018_10_15_095425_create_user_2fa_table.php b/resources/database/2018_10_15_095425_create_user_2fa_table.php
new file mode 100644
index 0000000..0adb7dd
--- /dev/null
+++ b/resources/database/2018_10_15_095425_create_user_2fa_table.php
@@ -0,0 +1,41 @@
+<?php
+
+use Illuminate\Support\Facades\Schema;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Database\Migrations\Migration;
+
+class CreateUser2faTable extends Migration
+{
+    /**
+     * Run the migrations.
+     *
+     * @return void
+     */
+    public function up()
+    {
+        Schema::create('user_2fa', function (Blueprint $table) {
+            $table->increments('id');
+            $table->unsignedInteger('user_id');
+            $table->boolean('google2fa_enable')->default(false);
+            $table->string('google2fa_secret')->nullable();
+            $table->timestamp('created_at')
+                ->default(DB::raw('CURRENT_TIMESTAMP'));
+            $table->timestamp('updated_at')
+                ->default(DB::raw('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'));
+
+            $table->foreign('user_id')
+                ->references('id')
+                ->on(config('lifeonscreen2fa.tables.user'));
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     *
+     * @return void
+     */
+    public function down()
+    {
+        Schema::dropIfExists('user_2fa');
+    }
+}
\ No newline at end of file
diff --git a/resources/views/authenticate.blade.php b/resources/views/authenticate.blade.php
new file mode 100644
index 0000000..4080b5f
--- /dev/null
+++ b/resources/views/authenticate.blade.php
@@ -0,0 +1,63 @@
+<!DOCTYPE html>
+<html lang="en" class="h-full font-sans">
+<head>
+    <meta charset="utf-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
+    <meta name="csrf-token" content="{{ csrf_token() }}">
+
+    <title>{{ Nova::name() }}</title>
+
+    <!-- Styles -->
+    <link rel="stylesheet" href="{{ mix('app.css', 'vendor/nova') }}">
+
+    <style>
+        body {
+            font-family: "Montserrat", sans-serif !important;
+        }
+
+        .btn,
+        .form-input,
+        .rounded-lg {
+            border-radius: 0 !important;
+        }
+    </style>
+</head>
+<body class="bg-40 text-black h-full">
+<div class="h-full">
+    <div class="px-view py-view mx-auto">
+        <div class="mx-auto py-8 max-w-sm text-center text-90">
+            @include('nova::partials.logo')
+        </div>
+
+        <form class="bg-white shadow rounded-lg p-8 max-w-xl mx-auto" method="POST" action="/los/2fa/authenticate">
+            <h2 class="p-2">Two Factor Authentication</h2>
+
+            <p class="p-2">Two factor authentication (2FA) strengthens access security by requiring two methods (also
+                referred to as factors) to
+                verify your identity.
+                Two factor authentication protects against phishing, social engineering and password brute force attacks
+                and secures your logins from attackers
+                exploiting weak or stolen credentials.</p>
+            <p class="p-2"><strong>Enter the pin from Google Authenticator Enable 2FA</strong></p>
+
+            <div class="text-center pt-3">
+                <div class="mb-6 w-1/2" style="display:inline-block">
+                    @if (isset($error))
+                    <p class="text-center font-semibold text-danger my-3">
+                        {{  $error }}
+                    </p>
+                    @endif
+                    <label class="block font-bold mb-2" for="co">One Time Password</label>
+                    <input class="form-control form-input form-input-bordered w-full" id="secret" type="number"
+                           name="secret" value="" required="required" autofocus="">
+
+                </div>
+                <button class="w-1/2 btn btn-default btn-primary hover:bg-primary-dark" type="submit">
+                    Authenticate
+                </button>
+            </div>
+        </form>
+    </div>
+</div>
+</body>
+</html>
diff --git a/resources/views/register.blade.php b/resources/views/register.blade.php
new file mode 100644
index 0000000..f33494d
--- /dev/null
+++ b/resources/views/register.blade.php
@@ -0,0 +1,71 @@
+<!DOCTYPE html>
+<html lang="en" class="h-full font-sans">
+<head>
+    <meta charset="utf-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
+    <meta name="csrf-token" content="{{ csrf_token() }}">
+
+    <title>{{ Nova::name() }}</title>
+
+    <!-- Styles -->
+    <link rel="stylesheet" href="{{ mix('app.css', 'vendor/nova') }}">
+
+    <style>
+        body {
+            font-family: "Montserrat", sans-serif !important;
+        }
+
+        .btn,
+        .form-input,
+        .rounded-lg {
+            border-radius: 0 !important;
+        }
+    </style>
+</head>
+<body class="bg-40 text-black h-full">
+<div class="h-full">
+    <div class="px-view py-view mx-auto">
+        <div class="mx-auto py-8 max-w-sm text-center text-90">
+            @include('nova::partials.logo')
+        </div>
+
+        <form class="bg-white shadow rounded-lg p-8 max-w-xl mx-auto" method="POST" action="/los/2fa/confirm">
+            <h2 class="p-2">Two Factor Authentication</h2>
+
+            <p class="p-2">Two factor authentication (2FA) strengthens access security by requiring two methods (also
+                referred
+                to as factors) to verify your identity. Two factor authentication protects against phishing, social
+                engineering and password brute force attacks and secures your logins from attackers exploiting weak
+                or stolen credentials.</p>
+            <p class="p-2">To Enable Two Factor Authentication on your Account, you need to do following steps</p>
+            <strong>
+                <ol>
+                    <li>Verify the OTP from Google Authenticator Mobile App</li>
+                </ol>
+            </strong>
+            <div class="text-center">
+                <img src="{{ $google2fa_url }}" alt="">
+            </div>
+
+            <div class="text-center">
+                <div class="mb-6 w-1/2" style="display:inline-block">
+                    @if (isset($error))
+                        <p class="text-center font-semibold text-danger my-3">
+                            {{  $error }}
+                        </p>
+                    @endif
+                    <label class="block font-bold mb-2" for="co">Secret</label>
+                    <input class="form-control form-input form-input-bordered w-full" id="secret" type="number"
+                           name="secret" value="" required="required" autofocus="">
+                </div>
+
+
+                <button class="w-1/2 btn btn-default btn-primary hover:bg-primary-dark" type="submit">
+                    Confirm
+                </button>
+            </div>
+        </form>
+    </div>
+</div>
+</body>
+</html>
diff --git a/routes/api.php b/routes/api.php
new file mode 100644
index 0000000..c2e1275
--- /dev/null
+++ b/routes/api.php
@@ -0,0 +1,13 @@
+<?php
+
+use Illuminate\Support\Facades\Route;
+
+/**
+ * This route is called when user must first time confirm secret
+ */
+Route::post('confirm', 'Lifeonscreen\Google2fa\Google2fa@confirm');
+
+/**
+ * This route is called to verify users secret
+ */
+Route::post('authenticate', 'Lifeonscreen\Google2fa\Google2fa@authenticate');
\ No newline at end of file
diff --git a/src/Google2FAAuthenticator.php b/src/Google2FAAuthenticator.php
new file mode 100644
index 0000000..cf76486
--- /dev/null
+++ b/src/Google2FAAuthenticator.php
@@ -0,0 +1,35 @@
+<?php
+
+namespace Lifeonscreen\Google2fa;
+
+use App\Exceptions\ValidationException;
+use PragmaRX\Google2FALaravel\Support\Authenticator;
+
+/**
+ * Class Google2FAAuthenticator
+ * @package Lifeonscreen\Google2fa
+ */
+class Google2FAAuthenticator extends Authenticator
+{
+    protected function canPassWithoutCheckingOTP()
+    {
+        return
+            !$this->isEnabled() ||
+            $this->noUserIsAuthenticated() ||
+            $this->twoFactorAuthStillValid();
+    }
+
+    /**
+     * @return mixed
+     * @throws ValidationException
+     */
+    protected function getGoogle2FASecretKey()
+    {
+        $secret = $this->getUser()->user2fa->{$this->config('otp_secret_column')};
+        if (is_null($secret) || empty($secret)) {
+            throw new ValidationException('Secret key cannot be empty.');
+        }
+
+        return $secret;
+    }
+}
\ No newline at end of file
diff --git a/src/Google2fa.php b/src/Google2fa.php
new file mode 100644
index 0000000..243f0ca
--- /dev/null
+++ b/src/Google2fa.php
@@ -0,0 +1,80 @@
+<?php
+
+namespace Lifeonscreen\Google2fa;
+
+use Laravel\Nova\Tool;
+use PragmaRX\Google2FA\Google2FA as G2fa;
+use Request;
+
+class Google2fa extends Tool
+{
+    /**
+     * Perform any tasks that need to happen when the tool is booted.
+     *
+     * @return void
+     */
+    public function boot()
+    {
+    }
+
+    /**
+     * Build the view that renders the navigation links for the tool.
+     *
+     * @return \Illuminate\View\View
+     */
+    public function renderNavigation()
+    {
+        return view('google2fa::navigation');
+    }
+
+    protected function is2FAValid()
+    {
+        $secret = Request::get('secret');
+
+        $google2fa = new G2fa();
+        $google2fa->setAllowInsecureCallToGoogleApis(true);
+
+        return $google2fa->verifyKey(auth()->user()->user2fa->google2fa_secret, $secret);
+    }
+
+    public function confirm()
+    {
+        if ($this->is2FAValid()) {
+            auth()->user()->user2fa->google2fa_enable = 1;
+            auth()->user()->user2fa->save();
+            $authenticator = app(Google2FAAuthenticator::class);
+            $authenticator->login();
+
+            return response()->redirectTo('/nova');
+        }
+
+        $google2fa = new G2fa();
+        $secretKey = $google2fa->generateSecretKey();
+        $google2fa->setAllowInsecureCallToGoogleApis(true);
+
+        $google2fa_url = $google2fa->getQRCodeGoogleUrl(
+            config('app.name'),
+            auth()->user()->email,
+            $secretKey
+        );
+
+        $data['google2fa_url'] = $google2fa_url;
+        $data['error'] = 'Secret is invalid.';
+
+        return view('google2fa::register', $data);
+
+    }
+
+    public function authenticate()
+    {
+        if ($this->is2FAValid()) {
+            $authenticator = app(Google2FAAuthenticator::class);
+            $authenticator->login();
+
+            return response()->redirectTo('/nova');
+        }
+        $data['error'] = 'One time password is invalid.';
+
+        return view('google2fa::authenticate', $data);
+    }
+}
diff --git a/src/Http/Middleware/Authorize.php b/src/Http/Middleware/Authorize.php
new file mode 100644
index 0000000..969b152
--- /dev/null
+++ b/src/Http/Middleware/Authorize.php
@@ -0,0 +1,20 @@
+<?php
+
+namespace Lifeonscreen\Google2fa\Http\Middleware;
+
+use Lifeonscreen\Google2fa\Google2fa;
+
+class Authorize
+{
+    /**
+     * Handle the incoming request.
+     *
+     * @param  \Illuminate\Http\Request  $request
+     * @param  \Closure  $next
+     * @return \Illuminate\Http\Response
+     */
+    public function handle($request, $next)
+    {
+        return resolve(Google2fa::class)->authorize($request) ? $next($request) : abort(403);
+    }
+}
diff --git a/src/Http/Middleware/Google2fa.php b/src/Http/Middleware/Google2fa.php
new file mode 100644
index 0000000..980dd90
--- /dev/null
+++ b/src/Http/Middleware/Google2fa.php
@@ -0,0 +1,57 @@
+<?php
+
+namespace Lifeonscreen\Google2fa\Http\Middleware;
+
+use Lifeonscreen\Google2fa\Models\User2fa;
+use Closure;
+use Lifeonscreen\Google2fa\Google2FAAuthenticator;
+use PragmaRX\Google2FA\Google2FA as G2fa;
+
+/**
+ * Class Google2fa
+ * @package Lifeonscreen\Google2fa\Http\Middleware
+ */
+class Google2fa
+{
+    /**
+     * Handle an incoming request.
+     *
+     * @param  \Illuminate\Http\Request $request
+     * @param  \Closure $next
+     * @return mixed
+     * @throws \PragmaRX\Google2FA\Exceptions\InsecureCallException
+     */
+    public function handle($request, Closure $next)
+    {
+        if ($request->path() == 'los/2fa/confirm' || $request->path() == 'los/2fa/authenticate') {
+            return $next($request);
+        }
+        $authenticator = app(Google2FAAuthenticator::class)->boot($request);
+        if (auth()->guest() || $authenticator->isAuthenticated()) {
+            return $next($request);
+        }
+        if (empty(auth()->user()->user2fa) || auth()->user()->user2fa->google2fa_enable === 0) {
+
+            $google2fa = new G2fa();
+            $secretKey = $google2fa->generateSecretKey();
+            $google2fa->setAllowInsecureCallToGoogleApis(true);
+
+            $google2fa_url = $google2fa->getQRCodeGoogleUrl(
+                config('app.name'),
+                auth()->user()->email,
+                $secretKey
+            );
+
+            $data['google2fa_url'] = $google2fa_url;
+            User2fa::where('user_id', auth()->user()->id)->delete();
+            User2fa::insert([
+                'user_id'          => auth()->user()->id,
+                'google2fa_secret' => $secretKey,
+            ]);
+
+            return response(view('google2fa::register', $data));
+        }
+
+        return response(view('google2fa::authenticate'));
+    }
+}
\ No newline at end of file
diff --git a/src/Models/User2fa.php b/src/Models/User2fa.php
new file mode 100644
index 0000000..0d2fb67
--- /dev/null
+++ b/src/Models/User2fa.php
@@ -0,0 +1,28 @@
+<?php
+
+namespace Lifeonscreen\Google2fa\Models;
+
+use Illuminate\Database\Eloquent\Model;
+use Illuminate\Database\Eloquent\Relations\BelongsTo;
+
+/**
+ * Class PasswordSecurity
+ * @package App\GraphQL\Models\User
+ */
+class User2fa extends Model
+{
+    /**
+     * @var string
+     */
+    protected $table   = 'user_2fa';
+
+    protected $guarded = [];
+
+    /**
+     * @return BelongsTo
+     */
+    public function user(): BelongsTo
+    {
+        return $this->belongsTo(config('lifeonscreen2fa.models.user'));
+    }
+}
\ No newline at end of file
diff --git a/src/ToolServiceProvider.php b/src/ToolServiceProvider.php
new file mode 100644
index 0000000..44ed367
--- /dev/null
+++ b/src/ToolServiceProvider.php
@@ -0,0 +1,59 @@
+<?php
+
+namespace Lifeonscreen\Google2fa;
+
+use Illuminate\Support\Facades\Route;
+use Illuminate\Support\ServiceProvider;
+use Lifeonscreen\Google2fa\Http\Middleware\Authorize;
+
+class ToolServiceProvider extends ServiceProvider
+{
+    /**
+     * Bootstrap any application services.
+     *
+     * @return void
+     */
+    public function boot()
+    {
+        $this->loadViewsFrom(__DIR__ . '/../resources/views', 'google2fa');
+        $this->loadMigrationsFrom(__DIR__ . '/../resources/database');
+
+        // Publishing is only necessary when using the CLI.
+        if ($this->app->runningInConsole()) {
+            // Publishing the configuration file.
+            $this->publishes([
+                __DIR__ . '/../config/lifeonscreen2fa.php' => config_path('lifeonscreen2fa.php'),
+            ], 'lifeonscreen2fa.config');
+        }
+
+        $this->app->booted(function () {
+            $this->routes();
+        });
+    }
+
+    /**
+     * Register the tool's routes.
+     *
+     * @return void
+     */
+    protected function routes()
+    {
+        if ($this->app->routesAreCached()) {
+            return;
+        }
+
+        Route::middleware(['nova', Authorize::class])
+            ->prefix('los/2fa')
+            ->group(__DIR__ . '/../routes/api.php');
+    }
+
+    /**
+     * Register any application services.
+     *
+     * @return void
+     */
+    public function register()
+    {
+        $this->mergeConfigFrom(__DIR__ . '/../config/lifeonscreen2fa.php', 'lifeonscreen2fa');
+    }
+}