mirror of
https://gitlab.linphone.org/BC/public/flexisip-account-manager.git
synced 2026-02-07 13:58:24 +00:00
Add email + sms auth
This commit is contained in:
parent
d73c952c76
commit
c115f4b45c
13 changed files with 414 additions and 38 deletions
|
|
@ -4,6 +4,7 @@ namespace App\Http\Controllers;
|
|||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
use App\Account;
|
||||
use App\Rules\SIP;
|
||||
|
|
@ -11,6 +12,8 @@ use App\Helpers\Utils;
|
|||
|
||||
class AccountController extends Controller
|
||||
{
|
||||
private $emailCodeSize = 14;
|
||||
|
||||
public function index(Request $request)
|
||||
{
|
||||
return view('account.index', [
|
||||
|
|
@ -23,12 +26,6 @@ class AccountController extends Controller
|
|||
return view('account.login');
|
||||
}
|
||||
|
||||
public function logout(Request $request)
|
||||
{
|
||||
Auth::logout();
|
||||
return redirect()->route('account.login');
|
||||
}
|
||||
|
||||
public function authenticate(Request $request)
|
||||
{
|
||||
$request->validate([
|
||||
|
|
@ -55,4 +52,94 @@ class AccountController extends Controller
|
|||
|
||||
return redirect()->back();
|
||||
}
|
||||
|
||||
public function loginEmail(Request $request)
|
||||
{
|
||||
return view('account.login_email');
|
||||
}
|
||||
|
||||
public function authenticateEmail(Request $request)
|
||||
{
|
||||
$request->validate(['email' => 'required|email|exists:external.accounts,email']);
|
||||
|
||||
$account = Account::where('email', $request->get('email'))->first();
|
||||
$account->confirmation_key = Str::random($this->emailCodeSize);
|
||||
$account->save();
|
||||
|
||||
// TODO send email
|
||||
|
||||
return view('account.authenticate_email', [
|
||||
'account' => $account
|
||||
]);
|
||||
}
|
||||
|
||||
public function authenticateEmailConfirm(Request $request, string $code)
|
||||
{
|
||||
$request->merge(['code' => $code]);
|
||||
$request->validate(['code' => 'required|size:'.$this->emailCodeSize]);
|
||||
|
||||
$account = Account::where('confirmation_key', $code)->firstOrFail();
|
||||
$account->confirmation_key = null;
|
||||
$account->save();
|
||||
|
||||
Auth::login($account);
|
||||
return redirect()->route('account.index');
|
||||
}
|
||||
|
||||
public function loginPhone(Request $request)
|
||||
{
|
||||
return view('account.login_phone');
|
||||
}
|
||||
|
||||
public function authenticatePhone(Request $request)
|
||||
{
|
||||
$request->validate(['phone' => 'required|starts_with:+|phone:AUTO']);
|
||||
|
||||
$account = Account::where('username', $request->get('phone'))->first();
|
||||
|
||||
// TODO add alias
|
||||
|
||||
if (!$account) {
|
||||
return view('account.login_phone')->withErrors([
|
||||
'phone' => 'Phone number not found'
|
||||
]);
|
||||
}
|
||||
|
||||
$account->confirmation_key = mt_rand(1000, 9999);
|
||||
$account->save();
|
||||
|
||||
// TODO send SMS
|
||||
|
||||
return view('account.authenticate_phone', [
|
||||
'account' => $account
|
||||
]);
|
||||
}
|
||||
|
||||
public function authenticatePhoneConfirm(Request $request)
|
||||
{
|
||||
$request->validate([
|
||||
'account_id' => 'required',
|
||||
'code' => 'required|digits:4'
|
||||
]);
|
||||
|
||||
$account = Account::where('id', $request->get('account_id'))->firstOrFail();
|
||||
|
||||
if ($account->confirmation_key != $request->get('code')) {
|
||||
return view('account.login_phone')->withErrors([
|
||||
'code' => 'Wrong code'
|
||||
]);
|
||||
}
|
||||
|
||||
$account->confirmation_key = null;
|
||||
$account->save();
|
||||
|
||||
Auth::login($account);
|
||||
return redirect()->route('account.index');
|
||||
}
|
||||
|
||||
public function logout(Request $request)
|
||||
{
|
||||
Auth::logout();
|
||||
return redirect()->route('account.login');
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ class AccountEmailController extends Controller
|
|||
|
||||
public function update(Request $request)
|
||||
{
|
||||
// TODO exists doesn't already exists
|
||||
$request->validate([
|
||||
'email' => 'required|email',
|
||||
'email_confirm' => 'required|same:email'
|
||||
|
|
|
|||
|
|
@ -12,7 +12,8 @@
|
|||
"fideloper/proxy": "^4.0",
|
||||
"laravel/framework": "^6.2",
|
||||
"laravel/tinker": "^2.0",
|
||||
"laravelcollective/html": "^6.1"
|
||||
"laravelcollective/html": "^6.1",
|
||||
"propaganistas/laravel-phone": "^4.2"
|
||||
},
|
||||
"require-dev": {
|
||||
"facade/ignition": "^1.4",
|
||||
|
|
|
|||
234
flexiapi/composer.lock
generated
234
flexiapi/composer.lock
generated
|
|
@ -4,7 +4,7 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "ba567a67313e8a2e9c9bfa01903053f8",
|
||||
"content-hash": "1188abce9cc741a1318f4f7db580e86f",
|
||||
"packages": [
|
||||
{
|
||||
"name": "dnoegel/php-xdg-base-dir",
|
||||
|
|
@ -334,6 +334,123 @@
|
|||
],
|
||||
"time": "2020-02-22T01:51:47+00:00"
|
||||
},
|
||||
{
|
||||
"name": "giggsey/libphonenumber-for-php",
|
||||
"version": "8.12.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/giggsey/libphonenumber-for-php.git",
|
||||
"reference": "198dffa12831e17320207ce1bd3b121402d2cc8d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/giggsey/libphonenumber-for-php/zipball/198dffa12831e17320207ce1bd3b121402d2cc8d",
|
||||
"reference": "198dffa12831e17320207ce1bd3b121402d2cc8d",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-mbstring": "*",
|
||||
"giggsey/locale": "^1.7",
|
||||
"php": ">=5.3.2"
|
||||
},
|
||||
"require-dev": {
|
||||
"pear/pear-core-minimal": "^1.9",
|
||||
"pear/pear_exception": "^1.0",
|
||||
"pear/versioncontrol_git": "^0.5",
|
||||
"phing/phing": "^2.7",
|
||||
"php-coveralls/php-coveralls": "^1.0|^2.0",
|
||||
"phpunit/phpunit": "^4.8.36|^5.0",
|
||||
"symfony/console": "^2.8|^3.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "8.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"libphonenumber\\": "src/"
|
||||
},
|
||||
"exclude-from-classmap": [
|
||||
"/src/data/",
|
||||
"/src/carrier/data/",
|
||||
"/src/geocoding/data/",
|
||||
"/src/timezone/data/"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"Apache-2.0"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Joshua Gigg",
|
||||
"email": "giggsey@gmail.com",
|
||||
"homepage": "https://giggsey.com/"
|
||||
}
|
||||
],
|
||||
"description": "PHP Port of Google's libphonenumber",
|
||||
"homepage": "https://github.com/giggsey/libphonenumber-for-php",
|
||||
"keywords": [
|
||||
"geocoding",
|
||||
"geolocation",
|
||||
"libphonenumber",
|
||||
"mobile",
|
||||
"phonenumber",
|
||||
"validation"
|
||||
],
|
||||
"time": "2020-03-30T08:29:12+00:00"
|
||||
},
|
||||
{
|
||||
"name": "giggsey/locale",
|
||||
"version": "1.8",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/giggsey/Locale.git",
|
||||
"reference": "85a1b251bad11c986fec2a051b10d4b80a5caa1b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/giggsey/Locale/zipball/85a1b251bad11c986fec2a051b10d4b80a5caa1b",
|
||||
"reference": "85a1b251bad11c986fec2a051b10d4b80a5caa1b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.2"
|
||||
},
|
||||
"require-dev": {
|
||||
"pear/pear-core-minimal": "^1.9",
|
||||
"pear/pear_exception": "^1.0",
|
||||
"pear/versioncontrol_git": "^0.5",
|
||||
"phing/phing": "~2.7",
|
||||
"php-coveralls/php-coveralls": "^1.0|^2.0",
|
||||
"phpunit/phpunit": "^4.8|^5.0",
|
||||
"symfony/console": "^2.8|^3.0|^4.0",
|
||||
"symfony/filesystem": "^2.8|^3.0|^4.0",
|
||||
"symfony/finder": "^2.8|^3.0|^4.0",
|
||||
"symfony/process": "^2.8|^3.0|^4.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Giggsey\\Locale\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Joshua Gigg",
|
||||
"email": "giggsey@gmail.com",
|
||||
"homepage": "http://giggsey.com/"
|
||||
}
|
||||
],
|
||||
"description": "Locale functions required by libphonenumber-for-php",
|
||||
"time": "2019-10-09T18:53:14+00:00"
|
||||
},
|
||||
{
|
||||
"name": "laravel/framework",
|
||||
"version": "v6.18.5",
|
||||
|
|
@ -790,6 +907,60 @@
|
|||
],
|
||||
"time": "2020-03-17T18:58:12+00:00"
|
||||
},
|
||||
{
|
||||
"name": "league/iso3166",
|
||||
"version": "2.1.5",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/thephpleague/iso3166.git",
|
||||
"reference": "aed3b32fc293afdf2c6c6a322c2408eb5d20804a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/thephpleague/iso3166/zipball/aed3b32fc293afdf2c6c6a322c2408eb5d20804a",
|
||||
"reference": "aed3b32fc293afdf2c6c6a322c2408eb5d20804a",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"friendsofphp/php-cs-fixer": "^2.12",
|
||||
"phpunit/phpunit": "^5.7.11 || ^6.0 || ^7.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "3.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"League\\ISO3166\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Rob Bast",
|
||||
"email": "rob.bast@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "ISO 3166-1 PHP Library",
|
||||
"homepage": "https://github.com/thephpleague/iso3166",
|
||||
"keywords": [
|
||||
"3166",
|
||||
"3166-1",
|
||||
"ISO 3166",
|
||||
"countries",
|
||||
"iso",
|
||||
"library"
|
||||
],
|
||||
"time": "2020-01-29T07:08:12+00:00"
|
||||
},
|
||||
{
|
||||
"name": "monolog/monolog",
|
||||
"version": "2.0.2",
|
||||
|
|
@ -1165,6 +1336,67 @@
|
|||
],
|
||||
"time": "2020-03-21T18:07:53+00:00"
|
||||
},
|
||||
{
|
||||
"name": "propaganistas/laravel-phone",
|
||||
"version": "4.2.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Propaganistas/Laravel-Phone.git",
|
||||
"reference": "a63ceba3678a666508d4bc6fbc611680b15d2f40"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/Propaganistas/Laravel-Phone/zipball/a63ceba3678a666508d4bc6fbc611680b15d2f40",
|
||||
"reference": "a63ceba3678a666508d4bc6fbc611680b15d2f40",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"giggsey/libphonenumber-for-php": "^7.0|^8.0",
|
||||
"illuminate/support": "^5.5|^6.0|^7.0",
|
||||
"illuminate/validation": "^5.5|^6.0|^7.0",
|
||||
"league/iso3166": "^2.0",
|
||||
"php": ">=7.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"orchestra/testbench": "*",
|
||||
"phpunit/phpunit": "*"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"laravel": {
|
||||
"providers": [
|
||||
"Propaganistas\\LaravelPhone\\PhoneServiceProvider"
|
||||
]
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Propaganistas\\LaravelPhone\\": "src/"
|
||||
},
|
||||
"files": [
|
||||
"src/helpers.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Propaganistas",
|
||||
"email": "Propaganistas@users.noreply.github.com"
|
||||
}
|
||||
],
|
||||
"description": "Adds phone number functionality to Laravel and Lumen based on Google's libphonenumber API.",
|
||||
"keywords": [
|
||||
"laravel",
|
||||
"libphonenumber",
|
||||
"lumen",
|
||||
"phone",
|
||||
"validation"
|
||||
],
|
||||
"time": "2020-03-03T16:55:31+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/container",
|
||||
"version": "1.0.0",
|
||||
|
|
|
|||
|
|
@ -118,6 +118,8 @@ return [
|
|||
'url' => 'The :attribute format is invalid.',
|
||||
'uuid' => 'The :attribute must be a valid UUID.',
|
||||
|
||||
'phone' => 'The :attribute field contains an invalid number.',
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Custom Validation Language Lines
|
||||
|
|
|
|||
|
|
@ -0,0 +1,9 @@
|
|||
@extends('layouts.main')
|
||||
|
||||
@section('content')
|
||||
@if (Auth::check())
|
||||
@include('parts.already_auth')
|
||||
@else
|
||||
<p>A unique authentication link was sent by email to {{ $account->email }}</p>
|
||||
@endif
|
||||
@endsection
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
@extends('layouts.main')
|
||||
|
||||
@section('content')
|
||||
@if (Auth::check())
|
||||
@include('parts.already_auth')
|
||||
@else
|
||||
<div class="card mt-3">
|
||||
<div class="card-body">
|
||||
{!! Form::open(['route' => 'account.authenticate_phone_confirm']) !!}
|
||||
<div class="form-group">
|
||||
{!! Form::label('code', 'Code') !!}
|
||||
{!! Form::hidden('account_id', $account->id) !!}
|
||||
{!! Form::text('code', old('code'), ['class' => 'form-control', 'placeholder' => '1234', 'required']) !!}
|
||||
</div>
|
||||
{!! Form::submit('Authenticate', ['class' => 'btn btn-primary']) !!}
|
||||
{!! Form::close() !!}
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
@endsection
|
||||
|
|
@ -2,10 +2,7 @@
|
|||
|
||||
@section('content')
|
||||
@if (Auth::check())
|
||||
<div class="alert alert-primary" role="alert">
|
||||
<a class="float-right" href="{{ route('logout') }}">Logout</a>
|
||||
You are already authenticated
|
||||
</div>
|
||||
@include('parts.already_auth')
|
||||
@else
|
||||
<div class="card mt-3">
|
||||
<div class="card-body">
|
||||
|
|
@ -20,6 +17,9 @@
|
|||
</div>
|
||||
{!! Form::submit('Authenticate', ['class' => 'btn btn-primary']) !!}
|
||||
{!! Form::close() !!}
|
||||
|
||||
<br />
|
||||
<p>You can also authenticate using your <a href="{{ route('account.login_email') }}">Email address</a> or your <a href="{{ route('account.login_phone') }}">Phone number</a></p>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
|
|
|
|||
19
flexiapi/resources/views/account/login_email.blade.php
Normal file
19
flexiapi/resources/views/account/login_email.blade.php
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
@extends('layouts.main')
|
||||
|
||||
@section('content')
|
||||
@if (Auth::check())
|
||||
@include('parts.already_auth')
|
||||
@else
|
||||
<div class="card mt-3">
|
||||
<div class="card-body">
|
||||
{!! Form::open(['route' => 'account.authenticate_email']) !!}
|
||||
<div class="form-group">
|
||||
{!! Form::label('email', 'Email') !!}
|
||||
{!! Form::email('email', old('email'), ['class' => 'form-control', 'placeholder' => 'myemail@address.org', 'required']) !!}
|
||||
</div>
|
||||
{!! Form::submit('Send the authentication link', ['class' => 'btn btn-primary']) !!}
|
||||
{!! Form::close() !!}
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
@endsection
|
||||
19
flexiapi/resources/views/account/login_phone.blade.php
Normal file
19
flexiapi/resources/views/account/login_phone.blade.php
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
@extends('layouts.main')
|
||||
|
||||
@section('content')
|
||||
@if (Auth::check())
|
||||
@include('parts.already_auth')
|
||||
@else
|
||||
<div class="card mt-3">
|
||||
<div class="card-body">
|
||||
{!! Form::open(['route' => 'account.authenticate_phone']) !!}
|
||||
<div class="form-group">
|
||||
{!! Form::label('phone', 'Phone') !!}
|
||||
{!! Form::text('phone', old('phone'), ['class' => 'form-control', 'placeholder' => '+123456789', 'required']) !!}
|
||||
</div>
|
||||
{!! Form::submit('Send the authentication code by SMS', ['class' => 'btn btn-primary']) !!}
|
||||
{!! Form::close() !!}
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
@endsection
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
@extends('layouts.main')
|
||||
|
||||
@section('content')
|
||||
@if (Auth::check())
|
||||
<div class="alert alert-primary" role="alert">
|
||||
<a class="float-right" href="{{ route('logout') }}">Logout</a>
|
||||
You are already authenticated
|
||||
</div>
|
||||
@else
|
||||
<div class="card mt-3">
|
||||
<div class="card-body">
|
||||
{!! Form::open(['route' => 'account.authenticate']) !!}
|
||||
<div class="form-group">
|
||||
{!! Form::label('username', 'Username') !!}
|
||||
{!! Form::text('username', old('username'), ['class' => 'form-control', 'placeholder' => 'username@sip.linphone.org', 'required']) !!}
|
||||
</div>
|
||||
<div class="form-group">
|
||||
{!! Form::label('password', 'Password') !!}
|
||||
{!! Form::password('password', ['class' => 'form-control', 'placeholder' => 'myPassword', 'required']) !!}
|
||||
</div>
|
||||
{!! Form::submit('Authenticate', ['class' => 'btn btn-primary']) !!}
|
||||
{!! Form::close() !!}
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
@endsection
|
||||
4
flexiapi/resources/views/parts/already_auth.blade.php
Normal file
4
flexiapi/resources/views/parts/already_auth.blade.php
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
<div class="alert alert-primary" role="alert">
|
||||
<a class="float-right" href="{{ route('logout') }}">Logout</a>
|
||||
You are already authenticated
|
||||
</div>
|
||||
|
|
@ -22,6 +22,14 @@
|
|||
Route::get('login', 'AccountController@login')->name('account.login');
|
||||
Route::post('authenticate', 'AccountController@authenticate')->name('account.authenticate');
|
||||
|
||||
Route::get('login/email', 'AccountController@loginEmail')->name('account.login_email');
|
||||
Route::post('authenticate/email', 'AccountController@authenticateEmail')->name('account.authenticate_email');
|
||||
Route::get('authenticate/email/{code}', 'AccountController@authenticateEmailConfirm')->name('account.authenticate_email_confirm');
|
||||
|
||||
Route::get('login/phone', 'AccountController@loginPhone')->name('account.login_phone');
|
||||
Route::post('authenticate/phone', 'AccountController@authenticatePhone')->name('account.authenticate_phone');
|
||||
Route::post('authenticate/phone/confirm', 'AccountController@authenticatePhoneConfirm')->name('account.authenticate_phone_confirm');
|
||||
|
||||
Route::group(['middleware' => 'auth'], function () {
|
||||
Route::get('/', 'AccountController@index')->name('account.index');
|
||||
Route::get('logout', 'AccountController@logout')->name('account.logout');
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue