Add two factor authentication

This commit is contained in:
2020-07-17 22:44:10 +01:00
parent 5f1f92a9ce
commit d392c0593f
24 changed files with 1010 additions and 21 deletions

View File

@@ -0,0 +1,36 @@
@extends('breadcrumbs.auth.main')
@section('authpage')
<div class="container">
<div class="card login-card">
<div class="row no-gutters">
<div class="col-md-5">
<img src="/img/login.jpg" alt="login" class="login-card-img">
</div>
<div class="col-md-7">
<div class="card-body">
<div class="brand-wrapper">
<img src="{{ config('adminlte.logo_img') }}" alt="logo" class="logo">{{ config('adminlte.logo') }}
</div>
<p class="login-card-description">Two-factor Authentication</p>
<form action="{{ route('verify2FA') }}" method="POST" id="verify">
@csrf
<div class="form-group">
<label for="name" class="sr-only">Two-factor secret code (You can find this on Google Authenticator)</label>
<input type="text" name="otp" id="name" class="form-control" placeholder="2FA Code (e.g. 543324)">
</div>
<input name="register" id="register" class="btn btn-block login-btn mb-4" type="submit" value="Send 2FA Code">
</form>
<p class="login-card-footer-text">Don't know the code? <a href="{{ route('logout') }}" class="text-reset">Cancel login (logout)</a></p>
<nav class="login-card-footer-nav">
<a href="#!">Terms of use</a>
<a href="#!">Privacy policy</a>
</nav>
</div>
</div>
</div>
</div>
</div>
@stop

View File

@@ -1 +1,44 @@
@extends('adminlte::auth.login')
@extends('breadcrumbs.auth.main')
@section('authpage')
<div class="container">
<div class="card login-card">
<div class="row no-gutters">
<div class="col-md-5">
<img src="/img/login.jpg" alt="login" class="login-card-img">
</div>
<div class="col-md-7">
<div class="card-body">
<div class="brand-wrapper">
<img src="{{ config('adminlte.logo_img') }}" alt="logo" class="logo">{{ config('adminlte.logo') }}
</div>
<p class="login-card-description">Sign into your account</p>
<form action="{{ route('login') }}" method="POST" id="loginForm">
@csrf
<div class="form-group">
<label for="email" class="sr-only">Email</label>
<input type="email" name="email" id="email" class="form-control" placeholder="Email address">
</div>
<div class="form-group mb-4">
<label for="password" class="sr-only">Password</label>
<input type="password" name="password" id="password" class="form-control" placeholder="***********">
</div>
<div class="form-group mb-4">
<label for="remember">Remember me</label>
<input type="checkbox" name="remember" id="remember" />
</div>
<input name="login" id="login" class="btn btn-block login-btn mb-4" type="submit" value="Sign-in">
</form>
<a href="{{ route('password.request') }}" class="forgot-password-link">Forgot password?</a>
<p class="login-card-footer-text">Don't have an account? <a href="{{ route('register') }}" class="text-reset">Register here</a></p>
<nav class="login-card-footer-nav">
<a href="#!">Terms of use</a>
<a href="#!">Privacy policy</a>
</nav>
</div>
</div>
</div>
</div>
</div>
@stop

View File

@@ -1 +1,53 @@
@extends('adminlte::auth.register')
@extends('breadcrumbs.auth.main')
@section('authpage')
<div class="container">
<div class="card login-card">
<div class="row no-gutters">
<div class="col-md-5">
<img src="/img/login.jpg" alt="login" class="login-card-img">
</div>
<div class="col-md-7">
<div class="card-body">
<div class="brand-wrapper">
<img src="{{ config('adminlte.logo_img') }}" alt="logo" class="logo">{{ config('adminlte.logo') }}
</div>
<p class="login-card-description">Register a new account</p>
<form action="{{ route('register') }}" method="POST" id="registerForm">
@csrf
<div class="form-group">
<label for="name" class="sr-only">Name</label>
<input type="text" name="name" id="name" class="form-control" placeholder="Name (e.g. John Smith)">
</div>
<div class="form-group mb-4">
<label for="email" class="sr-only">Email address</label>
<input type="email" name="email" id="email" class="form-control" placeholder="Email Address">
</div>
<div class="form-group mb-4">
<label for="password" class="sr-only">Password</label>
<input type="password" name="password" id="password" class="form-control" placeholder="Password"
</div>
<div class="form-group mb-4">
<label for="passwordc" class="sr-only">Confirm password</label>
<input type="password" id="passwordc" name="password_confirmation" class="form-control" placeholder="Confirm password" />
</div>
<div class="form-group mt-5">
<label for="mcusername" class="sr-only">Minecraft Username (Premium)</label>
<input type="text" name="uuid" class="form-control" id="mcusername" placeholder="Premium Minecraft Username (e.g. Notch)" />
</div>
<input name="register" id="register" class="btn btn-block login-btn mb-4" type="submit" value="Register">
</form>
<p class="login-card-footer-text">Have an account with us? <a href="{{ route('login') }}" class="text-reset">Login here</a></p>
<nav class="login-card-footer-nav">
<a href="#!">Terms of use</a>
<a href="#!">Privacy policy</a>
</nav>
</div>
</div>
</div>
</div>
</div>
@stop

View File

@@ -1 +1 @@
@extends('adminlte::auth.verify')
@extends('adminlte::auth.verify')

View File

@@ -18,7 +18,7 @@
@yield('content')
@include('breadcrumbs.footer')
@include('breadcrumbs.footer')
</body>

View File

@@ -0,0 +1,29 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>{{ config('app.name') . '| ID' }}</title>
<link href="https://fonts.googleapis.com/css?family=Karla:400,700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.materialdesignicons.com/4.8.95/css/materialdesignicons.min.css">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/toastr.min.css" />
<link rel="stylesheet" href="/css/login.css">
</head>
<body>
<main class="d-flex align-items-center min-vh-100 py-3 py-md-0">
@yield('authpage')
</main>
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/toastr@2.1.4/toastr.min.js"></script>
<x-global-errors></x-global-errors>
</body>

View File

@@ -19,6 +19,92 @@
@stop
@section('content')
@if (!Auth::user()->has2FA())
<x-modal id="twoFactorAuthModal" modal-label="2faLabel" modal-title="Two-factor Authentication" include-close-button="true">
<h3><i class="fas fa-user-shield"></i> We're glad you decided to increase your account's security!</h3>
<p><b>Supported apps you can install:</b></p>
<ul>
<li><a href="https://play.google.com/store/apps/details?id=com.google.android.apps.authenticator2&hl=en"><i class="fab fa-google-play"></i> Google Authenticator</a></li>
</ul>
<p>Scan the <i>QR code</i> below with your preferred app, and then copy the code here.</p>
<div class="row">
<div class="col-3 offset-3">
<div class="qr-code-container text-center">
<img src="{{ $twofaQRCode }}" alt="2FA Security key" />
</div>
</div>
</div>
<div class="row">
<div class="col">
<form method="POST" action="{{ route('enable2FA') }}" id="enable2Fa">
@csrf
@method('PATCH')
<label for="otp">One-time code</label>
<input type="text" id="otp" name="otp" class="form-control" />
</form>
</div>
</div>
<x-slot name="modalFooter">
<button type="button" class="btn btn-success" onclick="$('#enable2Fa').submit()"><i class="fas fa-key"></i> Enable 2FA</button>
</x-slot>
</x-modal>
@endif
@if (Auth::user()->has2FA())
<x-modal id="remove2FA" modal-label="remove2FALabel" modal-title="Remove Two-Factor Authentication" include-close-button="true">
<p><i class="fas fa-exclamation-triangle"></i> <b>Are you sure?</b> Removing two-factor authentication will reduce the security of your account.</p>
<form action="{{ route('disable2FA') }}" method="POST" id="disable2FA">
@csrf
@method('PATCH')
<label for="currentPassword">Confirm your password to continue</label>
<input id="currentPassword" type="password" name="currentPassword" class="form-control" required />
<p class="text-sm text-muted">To prevent unauthorized changes, a password is always required for sensitive operations.</p>
<div class="form-group mt-2">
<label for="consent">"I understand the possible consequences of disabling two factor authentication"</label>
<span><i>Click to confirm </i> </span><input type="checkbox" name="consent" id="consent" required />
</div>
</form>
<x-slot name="modalFooter">
<button type="button" class="btn btn-danger" onclick="$('#disable2FA').submit()"><i class="fa fa-trash"></i> Remove 2FA</button>
</x-slot>
</x-modal>
@endif
<div class="modal fade" tabindex="-1" id="authenticationForm" role="dialog" aria-labelledby="authenticationFormLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
@@ -116,8 +202,16 @@
</div>
<div class="tab-pane fade p-3" id="twofa" role="tabpanel" aria-labelledby="twofaTab">
<h5 class="card-title">Two-factor Authentication</h5>
<p class="card-text"><b>This feature is not yet available.</b> Support for Google Authenticator, Authy, Microsoft Authenticator and other compatible apps is coming soon, as well as fingerprint login for android devices.</p>
<button type="button" class="btn btn-primary" disabled>Enable 2FA</button>
<br />
@if (Auth::user()->has2FA())
<p><b>Hooray!</b> 2FA is setup correctly for your account. A code will be asked each time you login.</p>
<button type="button" class="btn btn-danger" onclick="$('#remove2FA').modal('show')"><i class="fa fa-ban"></i> Disable 2FA (not recommended)</button>
@else
<p class="card-text"><b>Two-factor auth is available for your account.</b> Enabling this security option greatly increases your account's security in case your password ever gets stolen.</p>
<button type="button" class="btn btn-primary" onclick="$('#twoFactorAuthModal').modal('show')">Enable 2FA</button>
@endif
</div>
<div class="tab-pane fade p-3" id="sessions" role="tabpanel" aria-labelledby="sessionsTab">
<h5 class="card-title">Session Manager</h5>