mirror of
https://github.com/CachetHQ/Cachet.git
synced 2025-03-14 20:39:44 +01:00
Merge pull request #342 from cachethq/tfa
[WIP] Two factor authentication
This commit is contained in:
commit
4ba88fa8cf
@ -135,6 +135,7 @@ return [
|
||||
'Thujohn\Rss\RssServiceProvider',
|
||||
'Jenssegers\Date\DateServiceProvider',
|
||||
'McCool\LaravelAutoPresenter\LaravelAutoPresenterServiceProvider',
|
||||
'PragmaRX\Google2FA\Vendor\Laravel\ServiceProvider',
|
||||
|
||||
/*
|
||||
* Application Service Providers...
|
||||
|
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class AlterTableUsersAdd2FA extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('users', function (Blueprint $table) {
|
||||
$table->string('google_2fa_secret')->after('remember_token');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('users', function (Blueprint $table) {
|
||||
$table->dropColumn('google_2fa_secret');
|
||||
});
|
||||
}
|
||||
}
|
@ -108,9 +108,10 @@ return [
|
||||
|
||||
// Login
|
||||
'login' => [
|
||||
'login' => 'Login',
|
||||
'logged_in' => "You're logged in.",
|
||||
'welcome' => 'Welcome Back!',
|
||||
'login' => 'Login',
|
||||
'logged_in' => 'You\'re logged in.',
|
||||
'welcome' => 'Welcome Back!',
|
||||
'two-factor' => 'Please enter your token.',
|
||||
],
|
||||
|
||||
// Sidebar footer
|
||||
|
@ -4,19 +4,21 @@ return [
|
||||
|
||||
// Setup form fields
|
||||
'setup' => [
|
||||
'email' => 'Email',
|
||||
'username' => 'Username',
|
||||
'password' => 'Password',
|
||||
'site_name' => 'Site Name',
|
||||
'site_domain' => 'Site Domain',
|
||||
'site_timezone' => 'Select your timezone',
|
||||
'site_locale' => 'Select your language',
|
||||
'email' => 'Email',
|
||||
'username' => 'Username',
|
||||
'password' => 'Password',
|
||||
'site_name' => 'Site Name',
|
||||
'site_domain' => 'Site Domain',
|
||||
'site_timezone' => 'Select your timezone',
|
||||
'site_locale' => 'Select your language',
|
||||
'enable_google2fa' => 'Enable Google Two Factor Authentication',
|
||||
],
|
||||
|
||||
// Login form fields
|
||||
'login' => [
|
||||
'email' => 'Email',
|
||||
'password' => 'Password',
|
||||
'2fauth' => 'Authentication Code',
|
||||
],
|
||||
|
||||
// Incidents form fields
|
||||
@ -79,6 +81,9 @@ return [
|
||||
'password' => 'Password',
|
||||
'api-key' => 'API Key',
|
||||
'api-key-help' => 'Regenerating your API key will revoke all existing applications.',
|
||||
'2fa' => [
|
||||
'help' => 'Enabling two factor authentication increases security of your account. You will need to download <a href="https://support.google.com/accounts/answer/1066447?hl=en">Google Authenticator</a> or a similar app on to your mobile device. When you login you will be asked to provide a token generated by the app.',
|
||||
],
|
||||
],
|
||||
|
||||
// Buttons
|
||||
|
@ -108,9 +108,10 @@ return [
|
||||
|
||||
// Login
|
||||
'login' => [
|
||||
'login' => 'Connexion',
|
||||
'logged_in' => "Vous êtes connecté.",
|
||||
'welcome' => 'Re-bonjour !',
|
||||
'login' => 'Connexion',
|
||||
'logged_in' => "Vous êtes connecté.",
|
||||
'welcome' => 'Re-bonjour !',
|
||||
'two-factor' => 'Please enter your token.',
|
||||
],
|
||||
|
||||
// Sidebar footer
|
||||
|
@ -4,19 +4,21 @@ return [
|
||||
|
||||
// Setup form fields
|
||||
'setup' => [
|
||||
'email' => 'Adresse email',
|
||||
'username' => 'Identifiant',
|
||||
'password' => 'Mot de passe',
|
||||
'site_name' => 'Nom du site',
|
||||
'site_domain' => 'Domaine du site',
|
||||
'site_timezone' => 'Sélectionnez votre fuseau horaire',
|
||||
'site_locale' => 'Sélectionnez votre langue',
|
||||
'email' => 'Adresse email',
|
||||
'username' => 'Identifiant',
|
||||
'password' => 'Mot de passe',
|
||||
'site_name' => 'Nom du site',
|
||||
'site_domain' => 'Domaine du site',
|
||||
'site_timezone' => 'Sélectionnez votre fuseau horaire',
|
||||
'site_locale' => 'Sélectionnez votre langue',
|
||||
'enable_google2fa' => 'Enable Google Two Factor Authentication',
|
||||
],
|
||||
|
||||
// Login form fields
|
||||
'login' => [
|
||||
'email' => 'Adresse email',
|
||||
'password' => 'Mot de passe',
|
||||
'2fauth' => 'Authentication Code',
|
||||
],
|
||||
|
||||
// Incidents form fields
|
||||
@ -79,6 +81,9 @@ return [
|
||||
'password' => 'Mot de passe',
|
||||
'api-key' => 'Clé API',
|
||||
'api-key-help' => 'Regénérer votre clé API révoquera toutes les applications existantes.',
|
||||
'2fa' => [
|
||||
'help' => 'Enabling two factor authentication increases security of your account. You will need to download <a href="https://support.google.com/accounts/answer/1066447?hl=en">Google Authenticator</a> or a similar app on to your mobile device. When you login you will be asked to provide a token generated by the app.',
|
||||
],
|
||||
],
|
||||
|
||||
// Buttons
|
||||
|
@ -1,6 +1,7 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
'dashboard' => 'Dashboard',
|
||||
|
||||
// Incidents
|
||||
@ -97,7 +98,7 @@ return [
|
||||
'stylesheet' => 'Folha de estilo',
|
||||
],
|
||||
'theme' => [
|
||||
'theme' => ' Tema',
|
||||
'theme' => 'Tema',
|
||||
],
|
||||
'edit' => [
|
||||
'success' => 'Configurações salvas.',
|
||||
@ -107,9 +108,10 @@ return [
|
||||
|
||||
// Login
|
||||
'login' => [
|
||||
'login' => 'Login',
|
||||
'logged_in' => "Você está logado.",
|
||||
'welcome' => 'Bem-vindo de volta!',
|
||||
'login' => 'Login',
|
||||
'logged_in' => "Você está logado.",
|
||||
'welcome' => 'Bem-vindo de volta!',
|
||||
'two-factor' => 'Please enter your token.',
|
||||
],
|
||||
|
||||
// Sidebar footer
|
||||
|
@ -3,19 +3,21 @@
|
||||
return [
|
||||
// Setup form fields
|
||||
'setup' => [
|
||||
'email' => 'Email',
|
||||
'username' => 'Usuário',
|
||||
'password' => 'Senha',
|
||||
'site_name' => 'Nome do site',
|
||||
'site_domain' => 'Domínio do site',
|
||||
'site_timezone' => 'Select your timezone',
|
||||
'site_locale' => 'Select your language',
|
||||
'email' => 'Email',
|
||||
'username' => 'Usuário',
|
||||
'password' => 'Senha',
|
||||
'site_name' => 'Nome do site',
|
||||
'site_domain' => 'Domínio do site',
|
||||
'site_timezone' => 'Select your timezone',
|
||||
'site_locale' => 'Select your language',
|
||||
'enable_google2fa' => 'Enable Google Two Factor Authentication',
|
||||
],
|
||||
|
||||
// Login form fields
|
||||
'login' => [
|
||||
'email' => 'Email',
|
||||
'password' => 'Senha',
|
||||
'2fauth' => 'Authentication Code',
|
||||
],
|
||||
|
||||
// Incidents form fields
|
||||
@ -78,6 +80,9 @@ return [
|
||||
'password' => 'Senha',
|
||||
'api-key' => 'Chave da API',
|
||||
'api-key-help' => 'Regenerar sua chave de API irá revogar todos os aplicativos existentes.',
|
||||
'2fa' => [
|
||||
'help' => 'Enabling two factor authentication increases security of your account. You will need to download <a href="https://support.google.com/accounts/answer/1066447?hl=en">Google Authenticator</a> or a similar app on to your mobile device. When you login you will be asked to provide a token generated by the app.',
|
||||
],
|
||||
],
|
||||
|
||||
// Buttons
|
||||
|
@ -1,22 +1,33 @@
|
||||
<?php
|
||||
|
||||
Route::group(['before' => 'has_setting:app_name', 'namespace' => 'CachetHQ\Cachet\Http\Controllers'], function () {
|
||||
// Login routes
|
||||
Route::get('/auth/login', [
|
||||
'before' => 'guest',
|
||||
'as' => 'login',
|
||||
'uses' => 'AuthController@showLogin',
|
||||
]);
|
||||
Route::post('/auth/login', [
|
||||
'before' => 'guest|csrf|login_throttling',
|
||||
'as' => 'logout',
|
||||
'uses' => 'AuthController@postLogin',
|
||||
]);
|
||||
});
|
||||
Route::group(['prefix' => 'auth', 'namespace' => 'CachetHQ\Cachet\Http\Controllers'], function () {
|
||||
Route::group(['before' => 'has_setting:app_name'], function () {
|
||||
// Login routes
|
||||
Route::get('login', [
|
||||
'before' => 'guest',
|
||||
'as' => 'login',
|
||||
'uses' => 'AuthController@showLogin',
|
||||
]);
|
||||
|
||||
Route::group(['before' => 'auth', 'namespace' => 'CachetHQ\Cachet\Http\Controllers'], function () {
|
||||
Route::get('/auth/logout', [
|
||||
'as' => 'logout',
|
||||
'uses' => 'AuthController@logoutAction',
|
||||
]);
|
||||
Route::post('login', [
|
||||
'before' => 'guest|csrf|login_throttling',
|
||||
'as' => 'logout',
|
||||
'uses' => 'AuthController@postLogin',
|
||||
]);
|
||||
|
||||
// Two factor authorization
|
||||
Route::get('2fa', [
|
||||
'as' => 'two-factor',
|
||||
'uses' => 'AuthController@showTwoFactorAuth',
|
||||
]);
|
||||
|
||||
Route::post('2fa', 'AuthController@postTwoFactor');
|
||||
});
|
||||
|
||||
Route::group(['before' => 'auth'], function () {
|
||||
Route::get('logout', [
|
||||
'as' => 'logout',
|
||||
'uses' => 'AuthController@logoutAction',
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
31
app/views/auth/two-factor-auth.blade.php
Normal file
31
app/views/auth/two-factor-auth.blade.php
Normal file
@ -0,0 +1,31 @@
|
||||
@extends('layout.clean')
|
||||
|
||||
@section('content')
|
||||
<div class="login">
|
||||
<div class="col-xs-12 col-xs-offset-0 col-sm-6 col-sm-offset-3 col-md-4 col-md-offset-4 text-center">
|
||||
<div class="welcome-logo">
|
||||
<img class="logo" height="50" src="{{ url('img/cachet-logo.svg') }}" alt="Cachet"/>
|
||||
</div>
|
||||
{{ Form::open() }}
|
||||
<fieldset>
|
||||
<legend>{{ trans('dashboard.login.two-factor') }}</legend>
|
||||
|
||||
@if(Session::has('error'))
|
||||
<p class="text-danger">{{ Session::get('error') }}</p>
|
||||
@endif
|
||||
|
||||
<div class="form-group">
|
||||
<label class="sr-only">{{ trans('forms.login.2fauth') }}</label>
|
||||
{{ Form::text('code', null, [
|
||||
'class' => 'form-control', 'placeholder' => trans('forms.login.2fauth'), 'required' => 'required'
|
||||
]) }}
|
||||
</div>
|
||||
<hr />
|
||||
<div class="form-group">
|
||||
<button type="submit" class="btn btn-lg btn-block btn-success">{{ trans('dashboard.login.login') }}</button>
|
||||
</div>
|
||||
</fieldset>
|
||||
{{ Form::close() }}
|
||||
</div>
|
||||
</div>
|
||||
@stop
|
@ -6,7 +6,7 @@
|
||||
<i class="icon ion-navicon"></i>
|
||||
</div>
|
||||
<span class="uppercase">
|
||||
<i class="ion ion-person"></i> {{ trans('dashboard.user.user') }}
|
||||
<i class="ion ion-person"></i> {{ trans('dashboard.team.member') }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="content-wrapper">
|
||||
@ -15,9 +15,9 @@
|
||||
@if($updated = Session::get('updated'))
|
||||
<div class="alert alert-{{ $updated ? 'success' : 'danger' }}">
|
||||
@if($updated)
|
||||
{{ sprintf("<strong>%s</strong> %s", trans('dashboard.notifications.awesome'), trans('dashboard.user.edit.success')) }}
|
||||
{{ sprintf("<strong>%s</strong> %s", trans('dashboard.notifications.awesome'), trans('dashboard.team.edit.success')) }}
|
||||
@else
|
||||
{{ sprintf("<strong>%s</strong> %s", trans('dashboard.notifications.whoops'), trans('dashboard.user.edit.failure')) }}
|
||||
{{ sprintf("<strong>%s</strong> %s", trans('dashboard.notifications.whoops'), trans('dashboard.team.edit.failure')) }}
|
||||
@endif
|
||||
</div>
|
||||
@endif
|
||||
|
@ -21,7 +21,7 @@
|
||||
<div class="user-grid">
|
||||
@foreach($teamMembers as $member)
|
||||
<div class="user col-sm-3 col-xs-6">
|
||||
<a href="/dashboard/team/{{ $member->id }}">
|
||||
<a href="@if(Auth::user()->id == $member->id) {{ url('dashboard/user') }} @else /dashboard/team/{{ $member->id }} @endif">
|
||||
<img src="{{ $member->gravatar }}" />
|
||||
</a>
|
||||
<div class="name">{{ $member->username }}</div>
|
||||
|
@ -15,9 +15,9 @@
|
||||
@if($updated = Session::get('updated'))
|
||||
<div class="alert alert-{{ $updated ? 'success' : 'danger' }}">
|
||||
@if($updated)
|
||||
{{ sprintf("<strong>%s</strong> %s", trans('dashboard.notifications.awesome'), trans('dashboard.user.edit.success')) }}
|
||||
{{ sprintf("<strong>%s</strong> %s", trans('dashboard.notifications.awesome'), trans('dashboard.team.edit.success')) }}
|
||||
@else
|
||||
{{ sprintf("<strong>%s</strong> %s", trans('dashboard.notifications.whoops'), trans('dashboard.user.edit.failure')) }}
|
||||
{{ sprintf("<strong>%s</strong> %s", trans('dashboard.notifications.whoops'), trans('dashboard.team.edit.failure')) }}
|
||||
@endif
|
||||
</div>
|
||||
@endif
|
||||
@ -42,6 +42,27 @@
|
||||
<input type="text" class="form-control" name="api_key" disabled value="{{ Auth::user()->api_key }}" />
|
||||
<span class="help-block">{{ trans('forms.user.api-key-help') }}</span>
|
||||
</div>
|
||||
<hr />
|
||||
<div class="form-group">
|
||||
<label class="checkbox-inline">
|
||||
<input type="hidden" name="google2fa" value="0" />
|
||||
<input type='checkbox' name="google2fa" value="1" {{ Auth::user()->hasTwoFactor ? "checked" : "" }} />
|
||||
{{ trans('forms.setup.enable_google2fa') }}
|
||||
</label>
|
||||
</div>
|
||||
@if(Auth::user()->hasTwoFactor)
|
||||
<div class="form-group">
|
||||
<?php
|
||||
$google2fa_url = PragmaRX\Google2FA\Vendor\Laravel\Facade::getQRCodeGoogleUrl(
|
||||
'CachetHQ',
|
||||
Auth::user()->email,
|
||||
Auth::user()->google_2fa_secret
|
||||
);
|
||||
?>
|
||||
<img src="{{ $google2fa_url }}" class="img-responsive" />
|
||||
<span class='help-block'>{{ trans('forms.user.2fa.help') }}</span>
|
||||
</div>
|
||||
@endif
|
||||
</fieldset>
|
||||
|
||||
<button type="submit" class="btn btn-success">{{ trans('forms.update') }}</button>
|
||||
|
@ -23,7 +23,8 @@
|
||||
"thujohn/rss": "~1.0",
|
||||
"watson/validating": "0.10.*",
|
||||
"jenssegers/date": "~2.0",
|
||||
"mccool/laravel-auto-presenter": "~2.2@dev"
|
||||
"mccool/laravel-auto-presenter": "~2.2@dev",
|
||||
"pragmarx/google2fa": "~0.1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "~4.3",
|
||||
|
54
composer.lock
generated
54
composer.lock
generated
@ -4,7 +4,7 @@
|
||||
"Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"hash": "b561fa017bd12ef775f7765fe28d8839",
|
||||
"hash": "54919d71db11cf852620b58cd12a982b",
|
||||
"packages": [
|
||||
{
|
||||
"name": "classpreloader/classpreloader",
|
||||
@ -1829,6 +1829,58 @@
|
||||
],
|
||||
"time": "2014-11-10 03:08:59"
|
||||
},
|
||||
{
|
||||
"name": "pragmarx/google2fa",
|
||||
"version": "v0.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/antonioribeiro/google2fa.git",
|
||||
"reference": "705c2ff3e59212636fdfe31405e0e667a4f31514"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/antonioribeiro/google2fa/zipball/705c2ff3e59212636fdfe31405e0e667a4f31514",
|
||||
"reference": "705c2ff3e59212636fdfe31405e0e667a4f31514",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.7"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpspec/phpspec": "~2.1@dev"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"component": "package",
|
||||
"frameworks": [
|
||||
"Laravel"
|
||||
]
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"PragmaRX\\Google2FA\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Antonio Carlos Ribeiro",
|
||||
"email": "acr@antoniocarlosribeiro.com",
|
||||
"role": "Creator & Designer"
|
||||
}
|
||||
],
|
||||
"description": "A One Time Password Authentication package, compatible with Google Authenticator.",
|
||||
"keywords": [
|
||||
"Authentication",
|
||||
"Two Factor Authentication",
|
||||
"google2fa",
|
||||
"laravel"
|
||||
],
|
||||
"time": "2014-09-22 15:53:31"
|
||||
},
|
||||
{
|
||||
"name": "predis/predis",
|
||||
"version": "v0.8.7",
|
||||
|
@ -8,7 +8,9 @@ use Illuminate\Routing\Controller;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Redirect;
|
||||
use Illuminate\Support\Facades\Request;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
use Illuminate\Support\Facades\View;
|
||||
use PragmaRX\Google2FA\Vendor\Laravel\Facade as Google2FA;
|
||||
|
||||
/**
|
||||
* Logs users into their account.
|
||||
@ -32,7 +34,22 @@ class AuthController extends Controller
|
||||
*/
|
||||
public function postLogin()
|
||||
{
|
||||
if (Auth::attempt(Binput::only(['email', 'password']))) {
|
||||
$loginData = Binput::only(['email', 'password']);
|
||||
// Validate login credentials.
|
||||
if (Auth::validate($loginData)) {
|
||||
// Log the user in for one request.
|
||||
Auth::once($loginData);
|
||||
// Do we have Two Factor Auth enabled?
|
||||
if (Auth::user()->hasTwoFactor) {
|
||||
// Temporarily store the user.
|
||||
Session::put('2fa_id', Auth::user()->id);
|
||||
|
||||
return Redirect::route('two-factor');
|
||||
}
|
||||
|
||||
// We probably wan't to add support for "Remember me" here.
|
||||
Auth::attempt(Binput::only(['email', 'password']));
|
||||
|
||||
return Redirect::intended('dashboard');
|
||||
}
|
||||
|
||||
@ -43,6 +60,47 @@ class AuthController extends Controller
|
||||
->with('error', 'Invalid email or password');
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows the two-factor-auth view.
|
||||
*
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function showTwoFactorAuth()
|
||||
{
|
||||
return View::make('auth.two-factor-auth');
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the Two Factor token.
|
||||
*
|
||||
* This feels very hacky, but we have to juggle authentication and codes.
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function postTwoFactor()
|
||||
{
|
||||
// Check that we have a session.
|
||||
if ($userId = Session::pull('2fa_id')) {
|
||||
$code = Binput::get('code');
|
||||
|
||||
// Maybe a temp login here.
|
||||
Auth::loginUsingId($userId);
|
||||
|
||||
$valid = Google2FA::verifyKey(Auth::user()->google_2fa_secret, $code);
|
||||
|
||||
if ($valid) {
|
||||
return Redirect::intended('dashboard');
|
||||
} else {
|
||||
// Failed login, log back out.
|
||||
Auth::logout();
|
||||
|
||||
return Redirect::route('login')->with('error', 'Invalid token');
|
||||
}
|
||||
}
|
||||
|
||||
return Redirect::route('login')->with('error', 'Invalid token');
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs the user out, deleting their session etc.
|
||||
*
|
||||
|
@ -8,6 +8,7 @@ use Illuminate\Routing\Controller;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Redirect;
|
||||
use Illuminate\Support\Facades\View;
|
||||
use PragmaRX\Google2FA\Vendor\Laravel\Facade as Google2FA;
|
||||
|
||||
class DashUserController extends Controller
|
||||
{
|
||||
@ -32,6 +33,20 @@ class DashUserController extends Controller
|
||||
{
|
||||
$items = Binput::all();
|
||||
|
||||
$passwordChange = array_get($items, 'password');
|
||||
$enable2FA = (bool) array_pull($items, 'google2fa');
|
||||
|
||||
// Let's enable/disable auth
|
||||
if ($enable2FA && ! Auth::user()->hasTwoFactor) {
|
||||
$items['google_2fa_secret'] = Google2FA::generateSecretKey();
|
||||
} elseif (! $enable2FA) {
|
||||
$items['google_2fa_secret'] = '';
|
||||
}
|
||||
|
||||
if (trim($passwordChange) === '') {
|
||||
unset($items['password']);
|
||||
}
|
||||
|
||||
$updated = Auth::user()->update($items);
|
||||
|
||||
return Redirect::back()->with('updated', $updated);
|
||||
|
@ -126,7 +126,6 @@ class SetupController extends Controller
|
||||
// Pull the user details out.
|
||||
$userDetails = array_pull($postData, 'user');
|
||||
|
||||
// TODO: Do we want to just use Model::unguard() here?
|
||||
$user = User::create([
|
||||
'username' => $userDetails['username'],
|
||||
'email' => $userDetails['email'],
|
||||
|
@ -44,7 +44,7 @@ class User extends Model implements UserInterface, RemindableInterface
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected $hidden = ['password', 'remember_token'];
|
||||
protected $hidden = ['password', 'remember_token', 'google_2fa_secret'];
|
||||
|
||||
/**
|
||||
* The properties that cannot be mass assigned.
|
||||
@ -133,4 +133,14 @@ class User extends Model implements UserInterface, RemindableInterface
|
||||
{
|
||||
return (bool) $this->level;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if a user has enabled two factor authentication.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getHasTwoFactorAttribute()
|
||||
{
|
||||
return trim($this->google_2fa_secret) !== '';
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user