From c115f4b45ca1d27fbaa98b1b4ee8ef3da996c4a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Jaussoin?= Date: Thu, 16 Apr 2020 18:07:17 +0200 Subject: [PATCH] Add email + sms auth --- .../Http/Controllers/AccountController.php | 99 +++++++- .../Controllers/AccountEmailController.php | 1 + flexiapi/composer.json | 3 +- flexiapi/composer.lock | 234 +++++++++++++++++- flexiapi/resources/lang/en/validation.php | 2 + .../account/authenticate_email.blade.php | 9 + .../account/authenticate_phone.blade.php | 20 ++ .../resources/views/account/login.blade.php | 8 +- .../views/account/login_email.blade.php | 19 ++ .../views/account/login_phone.blade.php | 19 ++ flexiapi/resources/views/home.blade.php | 26 -- .../views/parts/already_auth.blade.php | 4 + flexiapi/routes/web.php | 8 + 13 files changed, 414 insertions(+), 38 deletions(-) create mode 100644 flexiapi/resources/views/account/authenticate_email.blade.php create mode 100644 flexiapi/resources/views/account/authenticate_phone.blade.php create mode 100644 flexiapi/resources/views/account/login_email.blade.php create mode 100644 flexiapi/resources/views/account/login_phone.blade.php delete mode 100644 flexiapi/resources/views/home.blade.php create mode 100644 flexiapi/resources/views/parts/already_auth.blade.php diff --git a/flexiapi/app/Http/Controllers/AccountController.php b/flexiapi/app/Http/Controllers/AccountController.php index 56c7bff..9da1baa 100644 --- a/flexiapi/app/Http/Controllers/AccountController.php +++ b/flexiapi/app/Http/Controllers/AccountController.php @@ -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'); + } } diff --git a/flexiapi/app/Http/Controllers/AccountEmailController.php b/flexiapi/app/Http/Controllers/AccountEmailController.php index 4ea5af8..b181cd7 100644 --- a/flexiapi/app/Http/Controllers/AccountEmailController.php +++ b/flexiapi/app/Http/Controllers/AccountEmailController.php @@ -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' diff --git a/flexiapi/composer.json b/flexiapi/composer.json index 68d4f64..2d3e593 100644 --- a/flexiapi/composer.json +++ b/flexiapi/composer.json @@ -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", diff --git a/flexiapi/composer.lock b/flexiapi/composer.lock index 241d467..db55f47 100644 --- a/flexiapi/composer.lock +++ b/flexiapi/composer.lock @@ -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", diff --git a/flexiapi/resources/lang/en/validation.php b/flexiapi/resources/lang/en/validation.php index ce1d80d..429f8a2 100644 --- a/flexiapi/resources/lang/en/validation.php +++ b/flexiapi/resources/lang/en/validation.php @@ -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 diff --git a/flexiapi/resources/views/account/authenticate_email.blade.php b/flexiapi/resources/views/account/authenticate_email.blade.php new file mode 100644 index 0000000..92189e5 --- /dev/null +++ b/flexiapi/resources/views/account/authenticate_email.blade.php @@ -0,0 +1,9 @@ +@extends('layouts.main') + +@section('content') + @if (Auth::check()) + @include('parts.already_auth') + @else +

A unique authentication link was sent by email to {{ $account->email }}

+ @endif +@endsection \ No newline at end of file diff --git a/flexiapi/resources/views/account/authenticate_phone.blade.php b/flexiapi/resources/views/account/authenticate_phone.blade.php new file mode 100644 index 0000000..83ace7f --- /dev/null +++ b/flexiapi/resources/views/account/authenticate_phone.blade.php @@ -0,0 +1,20 @@ +@extends('layouts.main') + +@section('content') + @if (Auth::check()) + @include('parts.already_auth') + @else +
+
+ {!! Form::open(['route' => 'account.authenticate_phone_confirm']) !!} +
+ {!! Form::label('code', 'Code') !!} + {!! Form::hidden('account_id', $account->id) !!} + {!! Form::text('code', old('code'), ['class' => 'form-control', 'placeholder' => '1234', 'required']) !!} +
+ {!! Form::submit('Authenticate', ['class' => 'btn btn-primary']) !!} + {!! Form::close() !!} +
+
+ @endif +@endsection \ No newline at end of file diff --git a/flexiapi/resources/views/account/login.blade.php b/flexiapi/resources/views/account/login.blade.php index 55aa3c6..2ab5041 100644 --- a/flexiapi/resources/views/account/login.blade.php +++ b/flexiapi/resources/views/account/login.blade.php @@ -2,10 +2,7 @@ @section('content') @if (Auth::check()) - + @include('parts.already_auth') @else
@@ -20,6 +17,9 @@
{!! Form::submit('Authenticate', ['class' => 'btn btn-primary']) !!} {!! Form::close() !!} + +
+

You can also authenticate using your Email address or your Phone number

@endif diff --git a/flexiapi/resources/views/account/login_email.blade.php b/flexiapi/resources/views/account/login_email.blade.php new file mode 100644 index 0000000..3f1508f --- /dev/null +++ b/flexiapi/resources/views/account/login_email.blade.php @@ -0,0 +1,19 @@ +@extends('layouts.main') + +@section('content') + @if (Auth::check()) + @include('parts.already_auth') + @else +
+
+ {!! Form::open(['route' => 'account.authenticate_email']) !!} +
+ {!! Form::label('email', 'Email') !!} + {!! Form::email('email', old('email'), ['class' => 'form-control', 'placeholder' => 'myemail@address.org', 'required']) !!} +
+ {!! Form::submit('Send the authentication link', ['class' => 'btn btn-primary']) !!} + {!! Form::close() !!} +
+
+ @endif +@endsection \ No newline at end of file diff --git a/flexiapi/resources/views/account/login_phone.blade.php b/flexiapi/resources/views/account/login_phone.blade.php new file mode 100644 index 0000000..21a1a74 --- /dev/null +++ b/flexiapi/resources/views/account/login_phone.blade.php @@ -0,0 +1,19 @@ +@extends('layouts.main') + +@section('content') + @if (Auth::check()) + @include('parts.already_auth') + @else +
+
+ {!! Form::open(['route' => 'account.authenticate_phone']) !!} +
+ {!! Form::label('phone', 'Phone') !!} + {!! Form::text('phone', old('phone'), ['class' => 'form-control', 'placeholder' => '+123456789', 'required']) !!} +
+ {!! Form::submit('Send the authentication code by SMS', ['class' => 'btn btn-primary']) !!} + {!! Form::close() !!} +
+
+ @endif +@endsection \ No newline at end of file diff --git a/flexiapi/resources/views/home.blade.php b/flexiapi/resources/views/home.blade.php deleted file mode 100644 index 55aa3c6..0000000 --- a/flexiapi/resources/views/home.blade.php +++ /dev/null @@ -1,26 +0,0 @@ -@extends('layouts.main') - -@section('content') - @if (Auth::check()) - - @else -
-
- {!! Form::open(['route' => 'account.authenticate']) !!} -
- {!! Form::label('username', 'Username') !!} - {!! Form::text('username', old('username'), ['class' => 'form-control', 'placeholder' => 'username@sip.linphone.org', 'required']) !!} -
-
- {!! Form::label('password', 'Password') !!} - {!! Form::password('password', ['class' => 'form-control', 'placeholder' => 'myPassword', 'required']) !!} -
- {!! Form::submit('Authenticate', ['class' => 'btn btn-primary']) !!} - {!! Form::close() !!} -
-
- @endif -@endsection \ No newline at end of file diff --git a/flexiapi/resources/views/parts/already_auth.blade.php b/flexiapi/resources/views/parts/already_auth.blade.php new file mode 100644 index 0000000..7ffd292 --- /dev/null +++ b/flexiapi/resources/views/parts/already_auth.blade.php @@ -0,0 +1,4 @@ + \ No newline at end of file diff --git a/flexiapi/routes/web.php b/flexiapi/routes/web.php index 485e1d8..e721918 100644 --- a/flexiapi/routes/web.php +++ b/flexiapi/routes/web.php @@ -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');