Upgrade to Laravel 5.3

This commit is contained in:
Hillel Coren 2017-11-14 10:58:08 +02:00
parent 4e0d05b90e
commit 237a491a62
30 changed files with 976 additions and 915 deletions

View File

@ -39,7 +39,7 @@ The self-host zip includes all third party libraries whereas downloading the cod
* [Voice Commands](https://www.youtube.com/watch?v=w1ylz-q58cU) * [Voice Commands](https://www.youtube.com/watch?v=w1ylz-q58cU)
## Features ## Features
* Built using Laravel 5.2 * Built using Laravel 5.3
* Live PDF generation using [pdfmake](http://pdfmake.org/) * Live PDF generation using [pdfmake](http://pdfmake.org/)
* Supports 50+ payment gateways with [Omnipay](https://github.com/thephpleague/omnipay) * Supports 50+ payment gateways with [Omnipay](https://github.com/thephpleague/omnipay)
* Integrate with hundreds of apps with [Zapier](https://zapier.com/zapbook/invoice-ninja/) and [Integromat](https://www.integromat.com/en/integrations/invoiceninja) * Integrate with hundreds of apps with [Zapier](https://zapier.com/zapbook/invoice-ninja/) and [Integromat](https://www.integromat.com/en/integrations/invoiceninja)

View File

@ -4,6 +4,7 @@ namespace App\Exceptions;
use Crawler; use Crawler;
use Exception; use Exception;
use Illuminate\Auth\AuthenticationException;
use Illuminate\Auth\Access\AuthorizationException; use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Database\Eloquent\ModelNotFoundException; use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler; use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
@ -150,4 +151,31 @@ class Handler extends ExceptionHandler
return parent::render($request, $e); return parent::render($request, $e);
} }
} }
/**
* Convert an authentication exception into an unauthenticated response.
*
* @param \Illuminate\Http\Request $request
* @param \Illuminate\Auth\AuthenticationException $exception
* @return \Illuminate\Http\Response
*/
protected function unauthenticated($request, AuthenticationException $exception)
{
if ($request->expectsJson()) {
return response()->json(['error' => 'Unauthenticated.'], 401);
}
$guard = array_get($exception->guards(), 0);
switch ($guard) {
case 'client':
$url = '/client/login';
break;
default:
$url = '/login';
break;
}
return redirect()->guest($url);
}
} }

View File

@ -2,42 +2,13 @@
namespace App\Http\Controllers\Auth; namespace App\Http\Controllers\Auth;
use App\Events\UserLoggedIn; use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Models\User;
use App\Ninja\Repositories\AccountRepository; use App\Ninja\Repositories\AccountRepository;
use App\Services\AuthService; use App\Services\AuthService;
use Auth; use App\Http\Controllers\Controller;
use Event;
use Illuminate\Foundation\Auth\AuthenticatesAndRegistersUsers;
use Illuminate\Http\Request;
use Lang;
use Session;
use Utils;
use Cache;
use Illuminate\Contracts\Auth\Authenticatable;
use App\Http\Requests\ValidateTwoFactorRequest;
class AuthController extends Controller class AuthController extends Controller
{ {
/*
|--------------------------------------------------------------------------
| Registration & Login Controller
|--------------------------------------------------------------------------
|
| This controller handles the registration of new users, as well as the
| authentication of existing users. By default, this controller uses
| a simple trait to add these behaviors. Why don't you explore it?
|
*/
use AuthenticatesAndRegistersUsers;
/**
* @var string
*/
protected $redirectTo = '/dashboard';
/** /**
* @var AuthService * @var AuthService
*/ */
@ -63,43 +34,13 @@ class AuthController extends Controller
$this->authService = $authService; $this->authService = $authService;
} }
/**
* @param array $data
*
* @return mixed
*/
public function validator(array $data)
{
return Validator::make($data, [
'name' => 'required|max:255',
'email' => 'required|email|max:255|unique:users',
'password' => 'required|confirmed|min:6',
]);
}
/**
* Create a new user instance after a valid registration.
*
* @param array $data
*
* @return User
*/
public function create(array $data)
{
return User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => bcrypt($data['password']),
]);
}
/** /**
* @param $provider * @param $provider
* @param Request $request * @param Request $request
* *
* @return \Illuminate\Http\RedirectResponse * @return \Illuminate\Http\RedirectResponse
*/ */
public function authLogin($provider, Request $request) public function oauthLogin($provider, Request $request)
{ {
return $this->authService->execute($provider, $request->has('code')); return $this->authService->execute($provider, $request->has('code'));
} }
@ -107,161 +48,12 @@ class AuthController extends Controller
/** /**
* @return \Illuminate\Http\RedirectResponse * @return \Illuminate\Http\RedirectResponse
*/ */
public function authUnlink() public function oauthUnlink()
{ {
$this->accountRepo->unlinkUserFromOauth(Auth::user()); $this->accountRepo->unlinkUserFromOauth(auth()->user());
Session::flash('message', trans('texts.updated_settings')); session()->flash('message', trans('texts.updated_settings'));
return redirect()->to('/settings/' . ACCOUNT_USER_DETAILS); return redirect()->to('/settings/' . ACCOUNT_USER_DETAILS);
} }
/**
* @return \Illuminate\Http\Response
*/
public function getLoginWrapper()
{
if (auth()->check()) {
return redirect('/');
}
if (! Utils::isNinja() && ! User::count()) {
return redirect()->to('/setup');
}
if (Utils::isNinja() && ! Utils::isTravis()) {
// make sure the user is on SITE_URL/login to ensure OAuth works
$requestURL = request()->url();
$loginURL = SITE_URL . '/login';
$subdomain = Utils::getSubdomain(request()->url());
if ($requestURL != $loginURL && ! strstr($subdomain, 'webapp-')) {
return redirect()->to($loginURL);
}
}
return self::getLogin();
}
/**
* @param Request $request
*
* @return \Illuminate\Http\Response
*/
public function postLoginWrapper(Request $request)
{
$userId = Auth::check() ? Auth::user()->id : null;
$user = User::where('email', '=', $request->input('email'))->first();
if ($user && $user->failed_logins >= MAX_FAILED_LOGINS) {
Session::flash('error', trans('texts.invalid_credentials'));
return redirect()->to('login');
}
$response = self::postLogin($request);
if (Auth::check()) {
/*
$users = false;
// we're linking a new account
if ($request->link_accounts && $userId && Auth::user()->id != $userId) {
$users = $this->accountRepo->associateAccounts($userId, Auth::user()->id);
Session::flash('message', trans('texts.associated_accounts'));
// check if other accounts are linked
} else {
$users = $this->accountRepo->loadAccounts(Auth::user()->id);
}
*/
} elseif ($user) {
error_log('login failed');
$user->failed_logins = $user->failed_logins + 1;
$user->save();
}
return $response;
}
/**
* Send the post-authentication response.
*
* @param \Illuminate\Http\Request $request
* @param \Illuminate\Contracts\Auth\Authenticatable $user
* @return \Illuminate\Http\Response
*/
private function authenticated(Request $request, Authenticatable $user)
{
if ($user->google_2fa_secret) {
Auth::logout();
$request->session()->put('2fa:user:id', $user->id);
return redirect('/validate_two_factor/' . $user->account->account_key);
}
Event::fire(new UserLoggedIn());
return redirect()->intended($this->redirectTo);
}
/**
*
* @return \Illuminate\Http\Response
*/
public function getValidateToken()
{
if (session('2fa:user:id')) {
return view('auth.two_factor');
}
return redirect('login');
}
/**
*
* @param App\Http\Requests\ValidateSecretRequest $request
* @return \Illuminate\Http\Response
*/
public function postValidateToken(ValidateTwoFactorRequest $request)
{
//get user id and create cache key
$userId = $request->session()->pull('2fa:user:id');
$key = $userId . ':' . $request->totp;
//use cache to store token to blacklist
Cache::add($key, true, 4);
//login and redirect user
Auth::loginUsingId($userId);
Event::fire(new UserLoggedIn());
return redirect()->intended($this->redirectTo);
}
/**
* @return \Illuminate\Http\Response
*/
public function getLogoutWrapper()
{
if (Auth::check() && ! Auth::user()->registered) {
if (request()->force_logout) {
$account = Auth::user()->account;
$this->accountRepo->unlinkAccount($account);
if (! $account->hasMultipleAccounts()) {
$account->company->forceDelete();
}
$account->forceDelete();
} else {
return redirect('/');
}
}
$response = self::getLogout();
Session::flush();
$reason = htmlentities(request()->reason);
if (!empty($reason) && Lang::has("texts.{$reason}_logout")) {
Session::flash('warning', trans("texts.{$reason}_logout"));
}
return $response;
}
} }

View File

@ -0,0 +1,32 @@
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\SendsPasswordResetEmails;
class ForgotPasswordController extends Controller
{
/*
|--------------------------------------------------------------------------
| Password Reset Controller
|--------------------------------------------------------------------------
|
| This controller is responsible for handling password reset emails and
| includes a trait which assists in sending these notifications from
| your application to your users. Feel free to explore this trait.
|
*/
use SendsPasswordResetEmails;
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('guest');
}
}

View File

@ -0,0 +1,194 @@
<?php
namespace App\Http\Controllers\Auth;
use Utils;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Models\User;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
use Illuminate\Contracts\Auth\Authenticatable;
use Event;
use Cache;
use App\Events\UserLoggedIn;
use App\Http\Requests\ValidateTwoFactorRequest;
class LoginController extends Controller
{
/*
|--------------------------------------------------------------------------
| Login Controller
|--------------------------------------------------------------------------
|
| This controller handles authenticating users for the application and
| redirecting them to your home screen. The controller uses a trait
| to conveniently provide its functionality to your applications.
|
*/
use AuthenticatesUsers;
/**
* Where to redirect users after login.
*
* @var string
*/
protected $redirectTo = '/dashboard';
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('guest', ['except' => 'getLogoutWrapper']);
}
/**
* @return \Illuminate\Http\Response
*/
public function getLoginWrapper(Request $request)
{
if (auth()->check()) {
return redirect('/');
}
if (! Utils::isNinja() && ! User::count()) {
return redirect()->to('/setup');
}
if (Utils::isNinja() && ! Utils::isTravis()) {
// make sure the user is on SITE_URL/login to ensure OAuth works
$requestURL = request()->url();
$loginURL = SITE_URL . '/login';
$subdomain = Utils::getSubdomain(request()->url());
if ($requestURL != $loginURL && ! strstr($subdomain, 'webapp-')) {
return redirect()->to($loginURL);
}
}
return self::showLoginForm($request);
}
/**
* @param Request $request
*
* @return \Illuminate\Http\Response
*/
public function postLoginWrapper(Request $request)
{
$userId = auth()->check() ? auth()->user()->id : null;
$user = User::where('email', '=', $request->input('email'))->first();
if ($user && $user->failed_logins >= MAX_FAILED_LOGINS) {
session()->flash('error', trans('texts.invalid_credentials'));
return redirect()->to('login');
}
$response = self::login($request);
if (auth()->check()) {
/*
$users = false;
// we're linking a new account
if ($request->link_accounts && $userId && Auth::user()->id != $userId) {
$users = $this->accountRepo->associateAccounts($userId, Auth::user()->id);
Session::flash('message', trans('texts.associated_accounts'));
// check if other accounts are linked
} else {
$users = $this->accountRepo->loadAccounts(Auth::user()->id);
}
*/
} elseif ($user) {
error_log('login failed');
$user->failed_logins = $user->failed_logins + 1;
$user->save();
}
return $response;
}
/**
* Send the post-authentication response.
*
* @param \Illuminate\Http\Request $request
* @param \Illuminate\Contracts\Auth\Authenticatable $user
* @return \Illuminate\Http\Response
*/
private function authenticated(Request $request, Authenticatable $user)
{
if ($user->google_2fa_secret) {
auth()->logout();
session()->put('2fa:user:id', $user->id);
return redirect('/validate_two_factor/' . $user->account->account_key);
}
Event::fire(new UserLoggedIn());
return redirect()->intended($this->redirectTo);
}
/**
*
* @return \Illuminate\Http\Response
*/
public function getValidateToken()
{
if (session('2fa:user:id')) {
return view('auth.two_factor');
}
return redirect('login');
}
/**
*
* @param App\Http\Requests\ValidateSecretRequest $request
* @return \Illuminate\Http\Response
*/
public function postValidateToken(ValidateTwoFactorRequest $request)
{
//get user id and create cache key
$userId = session()->pull('2fa:user:id');
$key = $userId . ':' . $request->totp;
//use cache to store token to blacklist
Cache::add($key, true, 4);
//login and redirect user
auth()->loginUsingId($userId);
Event::fire(new UserLoggedIn());
return redirect()->intended($this->redirectTo);
}
/**
* @return \Illuminate\Http\Response
*/
public function getLogoutWrapper(Request $request)
{
if (auth()->check() && ! auth()->user()->registered) {
if (request()->force_logout) {
$account = auth()->user()->account;
$this->accountRepo->unlinkAccount($account);
if (! $account->hasMultipleAccounts()) {
$account->company->forceDelete();
}
$account->forceDelete();
} else {
return redirect('/');
}
}
$response = self::logout($request);
$reason = htmlentities(request()->reason);
if (!empty($reason) && Lang::has("texts.{$reason}_logout")) {
sesion()->flash('warning', trans("texts.{$reason}_logout"));
}
return $response;
}
}

View File

@ -7,7 +7,7 @@ use App\Events\UserLoggedIn;
use App\Http\Controllers\Controller; use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\ResetsPasswords; use Illuminate\Foundation\Auth\ResetsPasswords;
class PasswordController extends Controller class ResetPasswordController extends Controller
{ {
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
@ -21,40 +21,27 @@ class PasswordController extends Controller
*/ */
use ResetsPasswords { use ResetsPasswords {
getResetSuccessResponse as protected traitGetResetSuccessResponse; sendResetResponse as protected traitSendResetResponse;
} }
/** /**
* Where to redirect users after resetting their password.
*
* @var string * @var string
*/ */
protected $redirectTo = '/dashboard'; protected $redirectTo = '/dashboard';
/** /**
* Create a new password controller instance. * Create a new controller instance.
* *
* @internal param \Illuminate\Contracts\Auth\Guard $auth * @return void
* @internal param \Illuminate\Contracts\Auth\PasswordBroker $passwords
*/ */
public function __construct() public function __construct()
{ {
$this->middleware('guest'); $this->middleware('guest');
} }
/** protected function sendResetResponse($response)
* Display the form to request a password reset link.
*
* @return \Illuminate\Http\Response
*/
public function getEmailWrapper()
{
if (auth()->check()) {
return redirect('/');
}
return $this->getEmail();
}
protected function getResetSuccessResponse($response)
{ {
$user = auth()->user(); $user = auth()->user();
@ -64,7 +51,7 @@ class PasswordController extends Controller
return redirect('/validate_two_factor/' . $user->account->account_key); return redirect('/validate_two_factor/' . $user->account->account_key);
} else { } else {
Event::fire(new UserLoggedIn()); Event::fire(new UserLoggedIn());
return $this->traitGetResetSuccessResponse($response); return $this->traitSendResetResponse($response);
} }
} }
} }

View File

@ -0,0 +1,86 @@
<?php
namespace App\Http\Controllers\ClientAuth;
use Password;
use Config;
use App\Models\Contact;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\SendsPasswordResetEmails;
class ForgotPasswordController extends Controller
{
/*
|--------------------------------------------------------------------------
| Password Reset Controller
|--------------------------------------------------------------------------
|
| This controller is responsible for handling password reset emails and
| includes a trait which assists in sending these notifications from
| your application to your users. Feel free to explore this trait.
|
*/
use SendsPasswordResetEmails;
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('guest:client');
//Config::set('auth.defaults.passwords', 'client');
}
/**
* @return \Illuminate\Http\RedirectResponse
*/
public function showLinkRequestForm()
{
$data = [
'clientauth' => true,
];
if (! session('contact_key')) {
return \Redirect::to('/client/session_expired');
}
return view('clientauth.passwords.email')->with($data);
}
/**
* Send a reset link to the given user.
*
* @param \Illuminate\Http\Request $request
*
* @return \Illuminate\Http\Response
*/
public function sendResetLinkEmail(Request $request)
{
$contactId = null;
$contactKey = session('contact_key');
if ($contactKey) {
$contact = Contact::where('contact_key', '=', $contactKey)->first();
if ($contact && ! $contact->is_deleted && $contact->email) {
$contactId = $contact->id;
}
}
$response = $this->broker()->sendResetLink(['id' => $contactId], function (Message $message) {
$message->subject($this->getEmailSubject());
});
return $response == Password::RESET_LINK_SENT
? $this->sendResetLinkResponse($response)
: $this->sendResetLinkFailedResponse($request, $response);
}
protected function broker()
{
return Password::broker('clients');
}
}

View File

@ -2,32 +2,62 @@
namespace App\Http\Controllers\ClientAuth; namespace App\Http\Controllers\ClientAuth;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller; use App\Http\Controllers\Controller;
use App\Models\Contact; use App\Models\Contact;
use App\Models\User;
use Illuminate\Foundation\Auth\AuthenticatesUsers; use Illuminate\Foundation\Auth\AuthenticatesUsers;
use Illuminate\Http\Request;
use Session;
class AuthController extends Controller class LoginController extends Controller
{ {
/*
|--------------------------------------------------------------------------
| Login Controller
|--------------------------------------------------------------------------
|
| This controller handles authenticating users for the application and
| redirecting them to your home screen. The controller uses a trait
| to conveniently provide its functionality to your applications.
|
*/
use AuthenticatesUsers; use AuthenticatesUsers;
/** /**
* @var string * Where to redirect users after login.
*/ *
protected $guard = 'client';
/**
* @var string * @var string
*/ */
protected $redirectTo = '/client/dashboard'; protected $redirectTo = '/client/dashboard';
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('guest:client', ['except' => 'logout']);
}
/**
* Get the guard to be used during authentication.
*
* @return \Illuminate\Contracts\Auth\StatefulGuard
*/
protected function guard()
{
return auth()->guard('client');
}
/** /**
* @return mixed * @return mixed
*/ */
public function showLoginForm() public function showLoginForm()
{ {
if (! session('contact_key')) {
return redirect('/client/session_expired');
}
$data = [ $data = [
'clientauth' => true, 'clientauth' => true,
]; ];
@ -42,7 +72,7 @@ class AuthController extends Controller
* *
* @return array * @return array
*/ */
protected function getCredentials(Request $request) protected function credentials(Request $request)
{ {
$credentials = $request->only('password'); $credentials = $request->only('password');
$credentials['id'] = null; $credentials['id'] = null;
@ -59,7 +89,7 @@ class AuthController extends Controller
} }
/** /**
* Validate the user login request. * Validate the user login request - don't require the email
* *
* @param \Illuminate\Http\Request $request * @param \Illuminate\Http\Request $request
* *
@ -79,4 +109,5 @@ class AuthController extends Controller
{ {
return view('clientauth.sessionexpired')->with(['clientauth' => true]); return view('clientauth.sessionexpired')->with(['clientauth' => true]);
} }
} }

View File

@ -13,86 +13,6 @@ use Illuminate\Support\Facades\Password;
class PasswordController extends Controller class PasswordController extends Controller
{ {
/*
|--------------------------------------------------------------------------
| Password Reset Controller
|--------------------------------------------------------------------------
|
| This controller is responsible for handling password reset requests
| and uses a simple trait to include this behavior. You're free to
| explore this trait and override any methods you wish to tweak.
|
*/
use ResetsPasswords;
/**
* @var string
*/
protected $redirectTo = '/client/dashboard';
/**
* Create a new password controller instance.
*
* @internal param \Illuminate\Contracts\Auth\Guard $auth
* @internal param \Illuminate\Contracts\Auth\PasswordBroker $passwords
*/
public function __construct()
{
$this->middleware('guest');
Config::set('auth.defaults.passwords', 'client');
}
/**
* @return \Illuminate\Http\RedirectResponse
*/
public function showLinkRequestForm()
{
$data = [
'clientauth' => true,
];
if (! session('contact_key')) {
return \Redirect::to('/client/sessionexpired');
}
return view('clientauth.password')->with($data);
}
/**
* Send a reset link to the given user.
*
* @param \Illuminate\Http\Request $request
*
* @return \Illuminate\Http\Response
*/
public function sendResetLinkEmail(Request $request)
{
$broker = $this->getBroker();
$contactId = null;
$contactKey = session('contact_key');
if ($contactKey) {
$contact = Contact::where('contact_key', '=', $contactKey)->first();
if ($contact && ! $contact->is_deleted && $contact->email) {
$contactId = $contact->id;
}
}
$response = Password::broker($broker)->sendResetLink(['id' => $contactId], function (Message $message) {
$message->subject($this->getEmailSubject());
});
switch ($response) {
case Password::RESET_LINK_SENT:
return $this->getSendResetLinkEmailSuccessResponse($response);
case Password::INVALID_USER:
default:
return $this->getSendResetLinkEmailFailureResponse($response);
}
}
/** /**
* Display the password reset view for the given token. * Display the password reset view for the given token.
* *
@ -116,7 +36,7 @@ class PasswordController extends Controller
); );
if (! session('contact_key')) { if (! session('contact_key')) {
return \Redirect::to('/client/sessionexpired'); return \Redirect::to('/client/session_expired');
} }
return view('clientauth.reset')->with($data); return view('clientauth.reset')->with($data);

View File

@ -0,0 +1,61 @@
<?php
namespace App\Http\Controllers\ClientAuth;
use Password;
use Config;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\ResetsPasswords;
class ResetPasswordController extends Controller
{
/*
|--------------------------------------------------------------------------
| Password Reset Controller
|--------------------------------------------------------------------------
|
| This controller is responsible for handling password reset requests
| and uses a simple trait to include this behavior. You're free to
| explore this trait and override any methods you wish to tweak.
|
*/
use ResetsPasswords;
/**
* Where to redirect users after resetting their password.
*
* @var string
*/
protected $redirectTo = '/client/dashboard';
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('guest:client');
//Config::set('auth.defaults.passwords', 'client');
}
protected function broker()
{
return Password::broker('clients');
}
protected function guard()
{
return auth()->guard('clients');
}
public function showResetForm(Request $request, $token = null)
{
return view('clientauth.passwords.reset')->with(
['token' => $token, 'email' => $request->email]
);
}
}

View File

@ -93,7 +93,7 @@ class InvoiceController extends BaseController
->where('invitations.invoice_id', '=', $invoice->id) ->where('invitations.invoice_id', '=', $invoice->id)
->where('invitations.account_id', '=', Auth::user()->account_id) ->where('invitations.account_id', '=', Auth::user()->account_id)
->where('invitations.deleted_at', '=', null) ->where('invitations.deleted_at', '=', null)
->select('contacts.public_id')->lists('public_id'); ->select('contacts.public_id')->pluck('public_id');
$clients = Client::scope()->withTrashed()->with('contacts', 'country'); $clients = Client::scope()->withTrashed()->with('contacts', 'country');

View File

@ -64,7 +64,7 @@ class Authenticate
Session::put('contact_key', $contact->contact_key); Session::put('contact_key', $contact->contact_key);
} }
if (! $contact) { if (! $contact) {
return \Redirect::to('client/sessionexpired'); return \Redirect::to('client/session_expired');
} }
$account = $contact->account; $account = $contact->account;

View File

@ -39,12 +39,21 @@ class RedirectIfAuthenticated
* *
* @return mixed * @return mixed
*/ */
public function handle(Request $request, Closure $next) public function handle(Request $request, Closure $next, $guard = null)
{ {
if ($this->auth->check() && Client::scope()->count() > 0) { if (auth()->guard($guard)->check()) {
Session::reflash(); Session::reflash();
return new RedirectResponse(url('/dashboard')); switch ($guard) {
case 'client':
if (session('contact_key')) {
return redirect('/client/dashboard');
}
break;
default:
return redirect('/dashboard');
break;
}
} }
return $next($request); return $next($request);

View File

@ -79,39 +79,37 @@ Route::group(['middleware' => 'lookup:postmark'], function () {
Route::group(['middleware' => 'lookup:account'], function () { Route::group(['middleware' => 'lookup:account'], function () {
Route::post('/payment_hook/{account_key}/{gateway_id}', 'OnlinePaymentController@handlePaymentWebhook'); Route::post('/payment_hook/{account_key}/{gateway_id}', 'OnlinePaymentController@handlePaymentWebhook');
Route::match(['GET', 'POST', 'OPTIONS'], '/buy_now/{gateway_type?}', 'OnlinePaymentController@handleBuyNow'); Route::match(['GET', 'POST', 'OPTIONS'], '/buy_now/{gateway_type?}', 'OnlinePaymentController@handleBuyNow');
Route::get('validate_two_factor/{account_key}', 'Auth\AuthController@getValidateToken'); Route::get('validate_two_factor/{account_key}', 'Auth\LoginController@getValidateToken');
Route::post('validate_two_factor/{account_key}', ['middleware' => 'throttle:5', 'uses' => 'Auth\AuthController@postValidateToken']); Route::post('validate_two_factor/{account_key}', ['middleware' => 'throttle:5', 'uses' => 'Auth\LoginController@postValidateToken']);
}); });
//Route::post('/hook/bot/{platform?}', 'BotController@handleMessage'); //Route::post('/hook/bot/{platform?}', 'BotController@handleMessage');
// Laravel auth routes // Laravel auth routes
Route::get('/signup', ['as' => 'signup', 'uses' => 'Auth\AuthController@getRegister']); Route::get('/login', ['as' => 'login', 'uses' => 'Auth\LoginController@getLoginWrapper']);
Route::post('/signup', ['as' => 'signup', 'uses' => 'Auth\AuthController@postRegister']); Route::get('/logout', ['as' => 'logout', 'uses' => 'Auth\LoginController@getLogoutWrapper']);
Route::get('/login', ['as' => 'login', 'uses' => 'Auth\AuthController@getLoginWrapper']); Route::get('/recover_password', ['as' => 'forgot', 'uses' => 'Auth\ForgotPasswordController@showLinkRequestForm']);
Route::get('/logout', ['as' => 'logout', 'uses' => 'Auth\AuthController@getLogoutWrapper']); Route::get('/password/reset/{token}', ['as' => 'forgot', 'uses' => 'Auth\ResetPasswordController@showResetForm']);
Route::get('/recover_password', ['as' => 'forgot', 'uses' => 'Auth\PasswordController@getEmailWrapper']); Route::get('/auth/{provider}', 'Auth\AuthController@oauthLogin');
Route::get('/password/reset/{token}', ['as' => 'forgot', 'uses' => 'Auth\PasswordController@getReset']);
Route::get('/auth/{provider}', 'Auth\AuthController@authLogin');
Route::group(['middleware' => ['lookup:user']], function () { Route::group(['middleware' => ['lookup:user']], function () {
Route::get('/user/confirm/{confirmation_code}', 'UserController@confirm'); Route::get('/user/confirm/{confirmation_code}', 'UserController@confirm');
Route::post('/login', ['as' => 'login', 'uses' => 'Auth\AuthController@postLoginWrapper']); Route::post('/login', ['as' => 'login', 'uses' => 'Auth\LoginController@postLoginWrapper']);
Route::post('/recover_password', ['as' => 'forgot', 'uses' => 'Auth\PasswordController@postEmail']); Route::post('/recover_password', ['as' => 'forgot', 'uses' => 'Auth\ForgotPasswordController@sendResetLinkEmail']);
Route::post('/password/reset', ['as' => 'forgot', 'uses' => 'Auth\PasswordController@postReset']); Route::post('/password/reset', ['as' => 'forgot', 'uses' => 'Auth\ResetPasswordController@reset']);
}); });
// Client auth // Client auth
Route::get('/client/login', ['as' => 'login', 'uses' => 'ClientAuth\AuthController@getLogin']); Route::get('/client/login', ['as' => 'login', 'uses' => 'ClientAuth\LoginController@showLoginForm']);
Route::get('/client/logout', ['as' => 'logout', 'uses' => 'ClientAuth\AuthController@getLogout']); Route::get('/client/logout', ['as' => 'logout', 'uses' => 'ClientAuth\LoginController@getLogout']);
Route::get('/client/sessionexpired', ['as' => 'logout', 'uses' => 'ClientAuth\AuthController@getSessionExpired']); Route::get('/client/session_expired', ['as' => 'logout', 'uses' => 'ClientAuth\LoginController@getSessionExpired']);
Route::get('/client/recover_password', ['as' => 'forgot', 'uses' => 'ClientAuth\PasswordController@getEmail']); Route::get('/client/recover_password', ['as' => 'forgot', 'uses' => 'ClientAuth\ForgotPasswordController@showLinkRequestForm']);
Route::get('/client/password/reset/{token}', ['as' => 'forgot', 'uses' => 'ClientAuth\PasswordController@getReset']); Route::get('/client/password/reset/{token}', ['as' => 'forgot', 'uses' => 'Auth\ResetPasswordController@showResetForm']);
Route::group(['middleware' => ['lookup:contact']], function () { Route::group(['middleware' => ['lookup:contact']], function () {
Route::post('/client/login', ['as' => 'login', 'uses' => 'ClientAuth\AuthController@postLogin']); Route::post('/client/login', ['as' => 'login', 'uses' => 'ClientAuth\LoginController@login']);
Route::post('/client/recover_password', ['as' => 'forgot', 'uses' => 'ClientAuth\PasswordController@postEmail']); Route::post('/client/recover_password', ['as' => 'forgot', 'uses' => 'ClientAuth\ForgotPasswordController@sendResetLinkEmail']);
Route::post('/client/password/reset', ['as' => 'forgot', 'uses' => 'ClientAuth\PasswordController@postReset']); Route::post('/client/password/reset', ['as' => 'forgot', 'uses' => 'ClientAuth\ResetPasswordController@reset']);
}); });
if (Utils::isReseller()) { if (Utils::isReseller()) {
@ -137,7 +135,7 @@ Route::group(['middleware' => ['lookup:user', 'auth:user']], function () {
Route::post('signup/validate', 'AccountController@checkEmail'); Route::post('signup/validate', 'AccountController@checkEmail');
Route::post('signup/submit', 'AccountController@submitSignup'); Route::post('signup/submit', 'AccountController@submitSignup');
Route::get('auth_unlink', 'Auth\AuthController@authUnlink'); Route::get('auth_unlink', 'Auth\AuthController@oauthUnlink');
Route::get('settings/user_details', 'AccountController@showUserDetails'); Route::get('settings/user_details', 'AccountController@showUserDetails');
Route::post('settings/user_details', 'AccountController@saveUserDetails'); Route::post('settings/user_details', 'AccountController@saveUserDetails');

View File

@ -9,13 +9,20 @@ use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract; use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
use Illuminate\Database\Eloquent\SoftDeletes; use Illuminate\Database\Eloquent\SoftDeletes;
use App\Models\LookupContact; use App\Models\LookupContact;
use Illuminate\Notifications\Notifiable;
/** /**
* Class Contact. * Class Contact.
*/ */
class Contact extends EntityModel implements AuthenticatableContract, CanResetPasswordContract class Contact extends EntityModel implements AuthenticatableContract, CanResetPasswordContract
{ {
use SoftDeletes, Authenticatable, CanResetPassword; use SoftDeletes;
use Authenticatable;
use CanResetPassword;
use Notifiable;
protected $guard = 'client';
/** /**
* @var array * @var array
*/ */
@ -42,6 +49,17 @@ class Contact extends EntityModel implements AuthenticatableContract, CanResetPa
'custom_value2', 'custom_value2',
]; ];
/**
* The attributes excluded from the model's JSON form.
*
* @var array
*/
protected $hidden = [
'password',
'remember_token',
'confirmation_code',
];
/** /**
* @var string * @var string
*/ */

View File

@ -11,6 +11,7 @@ use Illuminate\Foundation\Auth\User as Authenticatable;
use Laracasts\Presenter\PresentableTrait; use Laracasts\Presenter\PresentableTrait;
use Session; use Session;
use App\Models\LookupUser; use App\Models\LookupUser;
use Illuminate\Notifications\Notifiable;
/** /**
* Class User. * Class User.
@ -19,6 +20,7 @@ class User extends Authenticatable
{ {
use PresentableTrait; use PresentableTrait;
use SoftDeletes; use SoftDeletes;
use Notifiable;
/** /**
* @var string * @var string

View File

@ -159,7 +159,7 @@ class DashboardRepository
$records->select(DB::raw('sum(expenses.amount + (expenses.amount * expenses.tax_rate1 / 100) + (expenses.amount * expenses.tax_rate2 / 100)) as total, count(expenses.id) as count, '.$timeframe.' as '.$groupBy)); $records->select(DB::raw('sum(expenses.amount + (expenses.amount * expenses.tax_rate1 / 100) + (expenses.amount * expenses.tax_rate2 / 100)) as total, count(expenses.id) as count, '.$timeframe.' as '.$groupBy));
} }
return $records->get(); return $records->get()->all();
} }
public function totals($accountId, $userId, $viewAll) public function totals($accountId, $userId, $viewAll)

View File

@ -10,6 +10,8 @@ use Utils;
use Validator; use Validator;
use Queue; use Queue;
use Illuminate\Queue\Events\JobProcessing; use Illuminate\Queue\Events\JobProcessing;
use Illuminate\Support\Facades\Route;
/** /**
* Class AppServiceProvider. * Class AppServiceProvider.
@ -23,6 +25,8 @@ class AppServiceProvider extends ServiceProvider
*/ */
public function boot() public function boot()
{ {
Route::singularResourceParameters(false);
// support selecting job database // support selecting job database
Queue::before(function (JobProcessing $event) { Queue::before(function (JobProcessing $event) {
$body = $event->job->getRawBody(); $body = $event->job->getRawBody();

View File

@ -2,6 +2,7 @@
namespace App\Providers; namespace App\Providers;
use Gate;
use Illuminate\Contracts\Auth\Access\Gate as GateContract; use Illuminate\Contracts\Auth\Access\Gate as GateContract;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider; use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
@ -41,12 +42,12 @@ class AuthServiceProvider extends ServiceProvider
* *
* @return void * @return void
*/ */
public function boot(GateContract $gate) public function boot()
{ {
foreach (get_class_methods(new \App\Policies\GenericEntityPolicy()) as $method) { foreach (get_class_methods(new \App\Policies\GenericEntityPolicy()) as $method) {
$gate->define($method, "App\Policies\GenericEntityPolicy@{$method}"); Gate::define($method, "App\Policies\GenericEntityPolicy@{$method}");
} }
$this->registerPolicies($gate); $this->registerPolicies();
} }
} }

View File

@ -2,7 +2,6 @@
namespace App\Providers; namespace App\Providers;
use Illuminate\Contracts\Events\Dispatcher as DispatcherContract;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider; use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
class EventServiceProvider extends ServiceProvider class EventServiceProvider extends ServiceProvider
@ -222,9 +221,9 @@ class EventServiceProvider extends ServiceProvider
* *
* @return void * @return void
*/ */
public function boot(DispatcherContract $events) public function boot()
{ {
parent::boot($events); parent::boot();
// //
} }

View File

@ -27,9 +27,9 @@ class RouteServiceProvider extends ServiceProvider
* *
* @return void * @return void
*/ */
public function boot(Router $router) public function boot()
{ {
parent::boot($router); parent::boot();
} }
/** /**

View File

@ -14,90 +14,60 @@
], ],
"require": { "require": {
"php": ">=5.5.9", "php": ">=5.5.9",
"laravel/framework": "5.3.*",
"laravelcollective/bus": "5.3.*",
"laravelcollective/html": "5.3.*",
"symfony/css-selector": "~3.1",
"invoiceninja/omnipay-collection": "0.4@dev",
"ext-gd": "*", "ext-gd": "*",
"ext-gmp": "*", "ext-gmp": "*",
"Dwolla/omnipay-dwolla": "dev-master",
"abdala/omnipay-pagseguro": "0.2",
"agmscode/omnipay-agms": "~1.0",
"alfaproject/omnipay-skrill": "dev-master",
"anahkiasen/former": "4.0.*@dev", "anahkiasen/former": "4.0.*@dev",
"andreas22/omnipay-fasapay": "1.*",
"asgrim/ofxparser": "^1.1", "asgrim/ofxparser": "^1.1",
"bacon/bacon-qr-code": "^1.0", "bacon/bacon-qr-code": "^1.0",
"barracudanetworks/archivestream-php": "^1.0", "barracudanetworks/archivestream-php": "^1.0",
"barryvdh/laravel-cors": "^0.9.1", "barryvdh/laravel-cors": "^0.9.1",
"barryvdh/laravel-debugbar": "~2.2", "barryvdh/laravel-debugbar": "~2.2",
"barryvdh/laravel-ide-helper": "~2.2", "barryvdh/laravel-ide-helper": "~2.2",
"cardgate/omnipay-cardgate": "~2.0",
"cerdic/css-tidy": "~v1.5", "cerdic/css-tidy": "~v1.5",
"chumper/datatable": "dev-develop#04ef2bf", "chumper/datatable": "dev-develop#04ef2bf",
"codedge/laravel-selfupdater": "5.x-dev", "codedge/laravel-selfupdater": "5.x-dev",
"collizo4sky/omnipay-wepay": "dev-address-fix",
"delatbabel/omnipay-fatzebra": "dev-master",
"dercoder/omnipay-ecopayz": "~1.0",
"dercoder/omnipay-paysafecard": "dev-master",
"descubraomundo/omnipay-pagarme": "dev-master",
"digitickets/omnipay-barclays-epdq": "~3.0",
"digitickets/omnipay-datacash": "~3.0",
"digitickets/omnipay-gocardlessv2": "dev-payment-fix",
"digitickets/omnipay-realex": "~5.0",
"dioscouri/omnipay-cybersource": "dev-master",
"doctrine/dbal": "2.5.x", "doctrine/dbal": "2.5.x",
"ezyang/htmlpurifier": "~v4.7", "ezyang/htmlpurifier": "~v4.7",
"fotografde/omnipay-checkoutcom": "~2.0",
"fruitcakestudio/omnipay-sisow": "~2.0",
"fzaninotto/faker": "^1.5", "fzaninotto/faker": "^1.5",
"gatepay/FedACHdir": "dev-master@dev", "gatepay/FedACHdir": "dev-master@dev",
"google/apiclient": "^2.0", "google/apiclient": "^2.0",
"guzzlehttp/guzzle": "~6.0", "guzzlehttp/guzzle": "~6.0",
"incube8/omnipay-multicards": "dev-master",
"intervention/image": "dev-master", "intervention/image": "dev-master",
"jaybizzle/laravel-crawler-detect": "1.*", "jaybizzle/laravel-crawler-detect": "1.*",
"jlapp/swaggervel": "master-dev", "jlapp/swaggervel": "master-dev",
"jonnyw/php-phantomjs": "4.*", "jonnyw/php-phantomjs": "4.*",
"justinbusschau/omnipay-secpay": "~2.0",
"laracasts/presenter": "dev-master", "laracasts/presenter": "dev-master",
"laravel/framework": "5.2.*",
"laravel/socialite": "~2.0", "laravel/socialite": "~2.0",
"laravelcollective/bus": "5.2.*",
"laravelcollective/html": "5.2.*",
"league/flysystem-aws-s3-v3": "~1.0", "league/flysystem-aws-s3-v3": "~1.0",
"league/flysystem-rackspace": "~1.0", "league/flysystem-rackspace": "~1.0",
"league/fractal": "0.13.*", "league/fractal": "0.13.*",
"lokielse/omnipay-alipay": "~1.4",
"maatwebsite/excel": "~2.0", "maatwebsite/excel": "~2.0",
"meebio/omnipay-creditcall": "dev-master",
"meebio/omnipay-secure-trading": "dev-master",
"mfauveau/omnipay-pacnet": "~2.0",
"mpdf/mpdf": "6.1.3", "mpdf/mpdf": "6.1.3",
"nwidart/laravel-modules": "^1.14", "nwidart/laravel-modules": "^1.14",
"omnipay/2checkout": "dev-master#e9c079c2dde0d7ba461903b3b7bd5caf6dee1248",
"omnipay/authorizenet": "dev-solution-id as 2.5.0",
"omnipay/bitpay": "dev-master",
"omnipay/braintree": "~2.0@dev",
"omnipay/gocardless": "dev-master",
"omnipay/mollie": "3.*",
"omnipay/omnipay": "~2.3",
"omnipay/stripe": "dev-master",
"patricktalmadge/bootstrapper": "5.5.x", "patricktalmadge/bootstrapper": "5.5.x",
"pragmarx/google2fa-laravel": "^0.1.2", "pragmarx/google2fa-laravel": "^0.1.2",
"predis/predis": "^1.1", "predis/predis": "^1.1",
"simshaun/recurr": "dev-master", "simshaun/recurr": "dev-master",
"softcommerce/omnipay-paytrace": "~1.0",
"symfony/css-selector": "~3.0",
"turbo124/laravel-push-notification": "2.*", "turbo124/laravel-push-notification": "2.*",
"vink/omnipay-komoju": "~1.0",
"webpatser/laravel-countries": "dev-master", "webpatser/laravel-countries": "dev-master",
"websight/l5-google-cloud-storage": "dev-master", "websight/l5-google-cloud-storage": "dev-master",
"wepay/php-sdk": "^0.2", "wepay/php-sdk": "^0.2",
"wildbit/laravel-postmark-provider": "3.0" "wildbit/laravel-postmark-provider": "3.0",
"omnipay/authorizenet": "dev-solution-id as 2.5.0",
"digitickets/omnipay-gocardlessv2": "dev-payment-fix",
"collizo4sky/omnipay-wepay": "dev-address-fix"
}, },
"require-dev": { "require-dev": {
"symfony/dom-crawler": "~3.1",
"codeception/c3": "~2.0", "codeception/c3": "~2.0",
"codeception/codeception": "2.3.3", "codeception/codeception": "2.3.3",
"phpspec/phpspec": "~2.1", "phpspec/phpspec": "~2.1",
"phpunit/phpunit": "~4.0", "phpunit/phpunit": "~4.0"
"symfony/dom-crawler": "~3.0"
}, },
"autoload": { "autoload": {
"classmap": [ "classmap": [
@ -137,6 +107,8 @@
"php artisan key:generate" "php artisan key:generate"
] ]
}, },
"minimum-stability": "dev",
"prefer-stable": true,
"config": { "config": {
"preferred-install": "dist", "preferred-install": "dist",
"sort-packages": true, "sort-packages": true,
@ -161,11 +133,11 @@
}, },
{ {
"type": "vcs", "type": "vcs",
"url": "https://github.com/hillelcoren/omnipay-wepay" "url": "https://github.com/hillelcoren/l5-google-cloud-storage"
}, },
{ {
"type": "vcs", "type": "vcs",
"url": "https://github.com/hillelcoren/l5-google-cloud-storage" "url": "https://github.com/hillelcoren/omnipay-wepay"
}, },
{ {
"type": "vcs", "type": "vcs",

918
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -4,6 +4,8 @@ use App\Libraries\Utils;
return [ return [
'name' => env('APP_NAME', 'Invoice Ninja'),
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------
| Application Debug Mode | Application Debug Mode
@ -139,6 +141,7 @@ return [
'Illuminate\Validation\ValidationServiceProvider', 'Illuminate\Validation\ValidationServiceProvider',
'Illuminate\View\ViewServiceProvider', 'Illuminate\View\ViewServiceProvider',
'Illuminate\Broadcasting\BroadcastServiceProvider', 'Illuminate\Broadcasting\BroadcastServiceProvider',
'Illuminate\Notifications\NotificationServiceProvider',
/* /*
* Additional Providers * Additional Providers

View File

@ -42,7 +42,7 @@ return [
'client' => [ 'client' => [
'driver' => 'session', 'driver' => 'session',
'provider' => 'client', 'provider' => 'clients',
], ],
'api' => [ 'api' => [
@ -74,7 +74,7 @@ return [
'model' => App\Models\User::class, 'model' => App\Models\User::class,
], ],
'client' => [ 'clients' => [
'driver' => 'eloquent', 'driver' => 'eloquent',
'model' => App\Models\Contact::class, 'model' => App\Models\Contact::class,
] ]
@ -102,13 +102,11 @@ return [
'passwords' => [ 'passwords' => [
'users' => [ 'users' => [
'provider' => 'users', 'provider' => 'users',
'email' => 'emails.password',
'table' => 'password_resets', 'table' => 'password_resets',
'expire' => 60, 'expire' => 60,
], ],
'client' => [ 'clients' => [
'provider' => 'client', 'provider' => 'clients',
'email' => 'emails.client_password',
'table' => 'password_resets', 'table' => 'password_resets',
'expire' => 60, 'expire' => 60,
], ],

View File

@ -2,7 +2,7 @@
@section('form') @section('form')
@include('partials.warn_session', ['redirectTo' => '/client/sessionexpired']) @include('partials.warn_session', ['redirectTo' => '/client/session_expired'])
<div class="container"> <div class="container">

View File

@ -1,7 +1,7 @@
@extends('login') @extends('login')
@section('form') @section('form')
@include('partials.warn_session', ['redirectTo' => '/client/sessionexpired']) @include('partials.warn_session', ['redirectTo' => '/client/session_expired'])
<div class="container"> <div class="container">
{!! Former::open('client/recover_password')->addClass('form-signin') !!} {!! Former::open('client/recover_password')->addClass('form-signin') !!}