mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2024-09-20 00:11:35 +02:00
Support clients logging in with email/password
This commit is contained in:
parent
7c1c8898a0
commit
bf1f540fdf
@ -2,10 +2,13 @@
|
||||
|
||||
namespace App\Http\Controllers\ClientAuth;
|
||||
|
||||
use Utils;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Contact;
|
||||
use App\Models\Account;
|
||||
use Illuminate\Foundation\Auth\AuthenticatesUsers;
|
||||
use Illuminate\Contracts\Auth\Authenticatable;
|
||||
|
||||
class LoginController extends Controller
|
||||
{
|
||||
@ -54,15 +57,22 @@ class LoginController extends Controller
|
||||
*/
|
||||
public function showLoginForm()
|
||||
{
|
||||
$subdomain = Utils::getSubdomain(\Request::server('HTTP_HOST'));
|
||||
$hasAccountIndentifier = request()->account_key || ($subdomain && $subdomain != 'app');
|
||||
|
||||
if (! session('contact_key')) {
|
||||
return redirect('/client/session_expired');
|
||||
if (Utils::isNinja()) {
|
||||
if (! $hasAccountIndentifier) {
|
||||
return redirect('/client/session_expired');
|
||||
}
|
||||
} else {
|
||||
if (! $hasAccountIndentifier && Account::count() > 1) {
|
||||
return redirect('/client/session_expired');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$data = [
|
||||
'clientauth' => true,
|
||||
];
|
||||
|
||||
return view('clientauth.login')->with($data);
|
||||
return view('clientauth.login')->with(['clientauth' => true]);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -74,20 +84,47 @@ class LoginController extends Controller
|
||||
*/
|
||||
protected function credentials(Request $request)
|
||||
{
|
||||
$credentials = $request->only('password');
|
||||
$credentials['id'] = null;
|
||||
if ($contactKey = session('contact_key')) {
|
||||
$credentials = $request->only('password');
|
||||
$credentials['contact_key'] = $contactKey;
|
||||
} else {
|
||||
$credentials = $request->only('email', 'password');
|
||||
$account = false;
|
||||
|
||||
$contactKey = session('contact_key');
|
||||
if ($contactKey) {
|
||||
$contact = Contact::where('contact_key', '=', $contactKey)->first();
|
||||
if ($contact && ! $contact->is_deleted) {
|
||||
$credentials['id'] = $contact->id;
|
||||
// resovle the email to a contact/account
|
||||
if ($accountKey = request()->account_key) {
|
||||
$account = Account::whereAccountKey($accountKey)->first();
|
||||
} else {
|
||||
$subdomain = Utils::getSubdomain(\Request::server('HTTP_HOST'));
|
||||
if ($subdomain != 'app') {
|
||||
$account = Account::whereSubdomain($subdomain)->first();
|
||||
}
|
||||
}
|
||||
|
||||
if ($account) {
|
||||
$credentials['account_id'] = $account->id;
|
||||
} else {
|
||||
abort(500, 'Account not resolved in client login');
|
||||
}
|
||||
}
|
||||
|
||||
return $credentials;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 $contact)
|
||||
{
|
||||
session(['contact_key' => $contact->contact_key]);
|
||||
|
||||
return redirect()->intended($this->redirectPath());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the failed login response instance.
|
||||
*
|
||||
@ -101,7 +138,7 @@ class LoginController extends Controller
|
||||
->withErrors([
|
||||
$this->username() => trans('texts.invalid_credentials'),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the user login request - don't require the email
|
||||
@ -112,9 +149,15 @@ class LoginController extends Controller
|
||||
*/
|
||||
protected function validateLogin(Request $request)
|
||||
{
|
||||
$this->validate($request, [
|
||||
$rules = [
|
||||
'password' => 'required',
|
||||
]);
|
||||
];
|
||||
|
||||
if (! session('contact_key')) {
|
||||
$rules['email'] = 'required|email';
|
||||
}
|
||||
|
||||
$this->validate($request, $rules);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -601,7 +601,7 @@ class ClientPortalController extends BaseController
|
||||
return response()->view('error', [
|
||||
'error' => $error ?: trans('texts.invoice_not_found'),
|
||||
'hideHeader' => true,
|
||||
'account' => $this->getContact()->account,
|
||||
'account' => $this->getContact() ? $this->getContact()->account : false,
|
||||
]);
|
||||
}
|
||||
|
||||
|
@ -44,6 +44,8 @@ class DatabaseLookup
|
||||
LookupInvitation::setServerByField('invitation_key', $key);
|
||||
} elseif ($key = request()->contact_key ?: session('contact_key')) {
|
||||
LookupContact::setServerByField('contact_key', $key);
|
||||
} elseif ($key = request()->account_key) {
|
||||
LookupAccount::setServerByField('account_key', $key);
|
||||
}
|
||||
} elseif ($guard == 'postmark') {
|
||||
LookupInvitation::setServerByField('message_id', request()->MessageID);
|
||||
|
@ -67,7 +67,7 @@ class LookupAccount extends LookupModel
|
||||
$lookupAccount = LookupAccount::whereAccountKey($accountKey)
|
||||
->firstOrFail();
|
||||
|
||||
$lookupAccount->subdomain = $account->subdomain;
|
||||
$lookupAccount->subdomain = $account->subdomain ?: null;
|
||||
$lookupAccount->save();
|
||||
|
||||
config(['database.default' => $current]);
|
||||
|
@ -236,4 +236,31 @@ class AccountPresenter extends Presenter
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function clientLoginUrl()
|
||||
{
|
||||
$account = $this->entity;
|
||||
|
||||
if (Utils::isNinjaProd()) {
|
||||
$url = 'https://';
|
||||
$url .= $account->subdomain ?: 'app';
|
||||
$url .= '.' . Domain::getDomainFromId($account->domain_id);
|
||||
} else {
|
||||
$url = SITE_URL;
|
||||
}
|
||||
|
||||
$url .= '/client/login';
|
||||
|
||||
if (Utils::isNinja()) {
|
||||
if (! $account->subdomain) {
|
||||
$url .= '?account_key=' . $account->account_key;
|
||||
}
|
||||
} else {
|
||||
if (Account::count() > 1) {
|
||||
$url .= '?account_key=' . $account->account_key;
|
||||
}
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
}
|
||||
|
@ -1050,7 +1050,7 @@ $LANG = array(
|
||||
// Client Passwords
|
||||
'enable_portal_password' => 'Password Protect Invoices',
|
||||
'enable_portal_password_help' => 'Allows you to set a password for each contact. If a password is set, the contact will be required to enter a password before viewing invoices.',
|
||||
'send_portal_password' => 'Generate Password Automatically',
|
||||
'send_portal_password' => 'Generate Automatically',
|
||||
'send_portal_password_help' => 'If no password is set, one will be generated and sent with the first invoice.',
|
||||
|
||||
'expired' => 'Expired',
|
||||
@ -2523,6 +2523,7 @@ $LANG = array(
|
||||
'local_storage_required' => 'Error: local storage is not available.',
|
||||
'your_password_reset_link' => 'Your Password Reset Link',
|
||||
'subdomain_taken' => 'The subdomain is already in use',
|
||||
'client_login' => 'Client Login',
|
||||
|
||||
);
|
||||
|
||||
|
@ -170,6 +170,10 @@
|
||||
->label(trans('texts.send_portal_password'))
|
||||
->value(1) !!}
|
||||
</div>
|
||||
<div class="col-md-10 col-md-offset-1">
|
||||
{!! Former::plaintext('client_login')
|
||||
->value(link_to($account->present()->clientLoginUrl, null, ['target' => '_blank'])) !!}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
<div class="container">
|
||||
|
||||
{!! Former::open('client/login')
|
||||
{!! Former::open()
|
||||
->rules(['password' => 'required'])
|
||||
->addClass('form-signin') !!}
|
||||
|
||||
@ -37,6 +37,9 @@
|
||||
{{ Former::populateField('remember', 'true') }}
|
||||
|
||||
<div>
|
||||
@if (! session('contact_key'))
|
||||
{!! Former::text('email')->placeholder(trans('texts.email'))->raw() !!}
|
||||
@endif
|
||||
{!! Former::password('password')->placeholder(trans('texts.password'))->raw() !!}
|
||||
</div>
|
||||
{!! Former::hidden('remember')->raw() !!}
|
||||
|
Loading…
Reference in New Issue
Block a user