mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-06-03 05:54:35 -04:00
Add support for including password in email; include portal customizations
This commit is contained in:
parent
793ba76415
commit
d0d30e1e26
@ -431,7 +431,6 @@ class AccountController extends BaseController
|
||||
$data = [
|
||||
'client_view_css' => $css,
|
||||
'enable_portal_password' => $account->enable_portal_password,
|
||||
'fill_portal_password' => $account->fill_portal_password,
|
||||
'send_portal_password' => $account->send_portal_password,
|
||||
'title' => trans("texts.client_portal"),
|
||||
'section' => ACCOUNT_CLIENT_PORTAL,
|
||||
@ -549,8 +548,8 @@ class AccountController extends BaseController
|
||||
$account = Auth::user()->account;
|
||||
$account->client_view_css = $sanitized_css;
|
||||
|
||||
$account->enable_client_portal = !!Input::get('enable_client_portal');
|
||||
$account->enable_portal_password = !!Input::get('enable_portal_password');
|
||||
$account->fill_portal_password = !!Input::get('fill_portal_password');
|
||||
$account->send_portal_password = !!Input::get('send_portal_password');
|
||||
|
||||
$account->save();
|
||||
|
@ -22,7 +22,24 @@ class AuthController extends Controller {
|
||||
|
||||
public function showLoginForm()
|
||||
{
|
||||
return view('clientauth.login');
|
||||
$data = array(
|
||||
);
|
||||
|
||||
$invitation_key = session('invitation_key');
|
||||
if($invitation_key){
|
||||
$invitation = Invitation::where('invitation_key', '=', $invitation_key)->first();
|
||||
if ($invitation && !$invitation->is_deleted) {
|
||||
$invoice = $invitation->invoice;
|
||||
$client = $invoice->client;
|
||||
$account = $client->account;
|
||||
|
||||
$data['hideLogo'] = $account->isWhiteLabel();
|
||||
$data['clientViewCSS'] = $account->clientViewCSS();
|
||||
$data['clientFontUrl'] = $account->getFontsUrl();
|
||||
}
|
||||
}
|
||||
|
||||
return view('clientauth.login')->with($data);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2,7 +2,6 @@
|
||||
|
||||
use Config;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Brokers\ClientPasswordBroker;
|
||||
use Illuminate\Foundation\Auth\ResetsPasswords;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Mail\Message;
|
||||
@ -42,7 +41,22 @@ class PasswordController extends Controller {
|
||||
|
||||
public function showLinkRequestForm()
|
||||
{
|
||||
return view('clientauth.password');
|
||||
$data = array();
|
||||
$invitation_key = session('invitation_key');
|
||||
if($invitation_key){
|
||||
$invitation = Invitation::where('invitation_key', '=', $invitation_key)->first();
|
||||
if ($invitation && !$invitation->is_deleted) {
|
||||
$invoice = $invitation->invoice;
|
||||
$client = $invoice->client;
|
||||
$account = $client->account;
|
||||
|
||||
$data['hideLogo'] = $account->isWhiteLabel();
|
||||
$data['clientViewCSS'] = $account->clientViewCSS();
|
||||
$data['clientFontUrl'] = $account->getFontsUrl();
|
||||
}
|
||||
}
|
||||
|
||||
return view('clientauth.password')->with($data);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -93,8 +107,23 @@ class PasswordController extends Controller {
|
||||
if (is_null($token)) {
|
||||
return $this->getEmail();
|
||||
}
|
||||
|
||||
$data = compact('token', 'invitation_key');
|
||||
$invitation_key = session('invitation_key');
|
||||
if($invitation_key){
|
||||
$invitation = Invitation::where('invitation_key', '=', $invitation_key)->first();
|
||||
if ($invitation && !$invitation->is_deleted) {
|
||||
$invoice = $invitation->invoice;
|
||||
$client = $invoice->client;
|
||||
$account = $client->account;
|
||||
|
||||
$data['hideLogo'] = $account->isWhiteLabel();
|
||||
$data['clientViewCSS'] = $account->clientViewCSS();
|
||||
$data['clientFontUrl'] = $account->getFontsUrl();
|
||||
}
|
||||
}
|
||||
|
||||
return view('clientauth.reset')->with(compact('token', 'invitation_key'));
|
||||
return view('clientauth.reset')->with($data);
|
||||
}
|
||||
|
||||
|
||||
|
@ -31,6 +31,7 @@ class ContactMailer extends Mailer
|
||||
'viewButton',
|
||||
'paymentLink',
|
||||
'paymentButton',
|
||||
'password',
|
||||
];
|
||||
|
||||
public function sendInvoice(Invoice $invoice, $reminder = false, $pdfString = false)
|
||||
@ -109,6 +110,13 @@ class ContactMailer extends Mailer
|
||||
'invitation' => $invitation,
|
||||
'amount' => $invoice->getRequestedAmount()
|
||||
];
|
||||
|
||||
if (empty($invitation->contact->password) && $account->isPro() && $account->enable_portal_password && $account->send_portal_password) {
|
||||
// The contact needs a password
|
||||
$variables['password'] = $password = $this->generatePassword();
|
||||
$invitation->contact->password = bcrypt($password);
|
||||
$invitation->contact->save();
|
||||
}
|
||||
|
||||
$data = [
|
||||
'body' => $this->processVariables($body, $variables),
|
||||
@ -143,6 +151,28 @@ class ContactMailer extends Mailer
|
||||
return $response;
|
||||
}
|
||||
}
|
||||
|
||||
protected function generatePassword($length = 9)
|
||||
{
|
||||
$sets = array(
|
||||
'abcdefghjkmnpqrstuvwxyz',
|
||||
'ABCDEFGHJKMNPQRSTUVWXYZ',
|
||||
'23456789',
|
||||
);
|
||||
$all = '';
|
||||
$password = '';
|
||||
foreach($sets as $set)
|
||||
{
|
||||
$password .= $set[array_rand(str_split($set))];
|
||||
$all .= $set;
|
||||
}
|
||||
$all = str_split($all);
|
||||
for($i = 0; $i < $length - count($sets); $i++)
|
||||
$password .= $all[array_rand($all)];
|
||||
$password = str_shuffle($password);
|
||||
|
||||
return $password;
|
||||
}
|
||||
|
||||
public function sendPaymentConfirmation(Payment $payment)
|
||||
{
|
||||
@ -253,6 +283,7 @@ class ContactMailer extends Mailer
|
||||
'$customClient2' => $account->custom_client_label2,
|
||||
'$customInvoice1' => $account->custom_invoice_text_label1,
|
||||
'$customInvoice2' => $account->custom_invoice_text_label2,
|
||||
'$password' => isset($data['password'])?$data['password']:false,
|
||||
];
|
||||
|
||||
// Add variables for available payment types
|
||||
|
@ -14,7 +14,6 @@ class AddClientPassword extends Migration {
|
||||
{
|
||||
Schema::table('accounts', function ($table) {
|
||||
$table->boolean('enable_portal_password')->default(0);
|
||||
$table->boolean('fill_portal_password')->default(0);
|
||||
$table->boolean('send_portal_password')->default(0);
|
||||
});
|
||||
|
||||
@ -34,7 +33,6 @@ class AddClientPassword extends Migration {
|
||||
{
|
||||
Schema::table('accounts', function ($table) {
|
||||
$table->dropColumn('enable_portal_password');
|
||||
$table->dropColumn('fill_portal_password');
|
||||
$table->dropColumn('send_portal_password');
|
||||
});
|
||||
|
||||
|
@ -1053,10 +1053,10 @@ $LANG = array(
|
||||
'enable_client_portal_help' => 'Show/hide the dashboard page in the client portal.',
|
||||
|
||||
// Client Passwords
|
||||
'client_portal_login_settings'=>'Login',
|
||||
'enable_portal_password'=>'Require a password',
|
||||
'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',
|
||||
'fill_portal_password'=>'Include password in invoice emails',
|
||||
'send_portal_password_help'=>'If no password is set, one will be generated and sent with the first invoice.',
|
||||
);
|
||||
|
||||
return $LANG;
|
||||
|
@ -15,6 +15,7 @@
|
||||
{!! Former::populateField('enable_client_portal', intval($account->enable_client_portal)) !!}
|
||||
{!! Former::populateField('client_view_css', $client_view_css) !!}
|
||||
{!! Former::populateField('enable_portal_password', $enable_portal_password) !!}
|
||||
{!! Former::populateField('send_portal_password', $send_portal_password) !!}
|
||||
|
||||
@if (!Utils::isNinja() && !Auth::user()->account->isWhiteLabel())
|
||||
<div class="alert alert-warning" style="font-size:larger;">
|
||||
@ -40,16 +41,13 @@
|
||||
<div class="col-md-10 col-md-offset-1">
|
||||
{!! Former::checkbox('enable_portal_password')
|
||||
->text(trans('texts.enable_portal_password'))
|
||||
->label(' ') !!}
|
||||
</div>
|
||||
<div class="col-md-10 col-md-offset-1">
|
||||
{!! Former::checkbox('fill_portal_password')
|
||||
->text(trans('texts.fill_portal_password'))
|
||||
->help(trans('texts.enable_portal_password_help'))
|
||||
->label(' ') !!}
|
||||
</div>
|
||||
<div class="col-md-10 col-md-offset-1">
|
||||
{!! Former::checkbox('send_portal_password')
|
||||
->text(trans('texts.send_portal_password'))
|
||||
->help(trans('texts.send_portal_password_help'))
|
||||
->label(' ') !!}
|
||||
</div>
|
||||
</div>
|
||||
@ -67,7 +65,6 @@
|
||||
->autofocus()
|
||||
->maxlength(60000)
|
||||
->style("min-width:100%;max-width:100%;font-family:'Roboto Mono', 'Lucida Console', Monaco, monospace;font-size:14px;'") !!}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -82,7 +79,6 @@
|
||||
$('#enable_portal_password').change(fixCheckboxes);
|
||||
function fixCheckboxes(){
|
||||
var checked = $('#enable_portal_password').is(':checked');
|
||||
$('#fill_portal_password').prop('disabled', !checked);
|
||||
$('#send_portal_password').prop('disabled', !checked);
|
||||
}
|
||||
fixCheckboxes();
|
||||
|
@ -1,10 +1,7 @@
|
||||
@extends('master')
|
||||
@extends('public.header')
|
||||
|
||||
@section('head')
|
||||
|
||||
<link href="{{ asset('css/bootstrap.min.css') }}" rel="stylesheet" type="text/css"/>
|
||||
<link href="{{ asset('css/style.css') }}" rel="stylesheet" type="text/css"/>
|
||||
|
||||
@parent
|
||||
<style type="text/css">
|
||||
body {
|
||||
padding-top: 40px;
|
||||
@ -13,6 +10,8 @@
|
||||
.modal-header {
|
||||
border-top-left-radius: 3px;
|
||||
border-top-right-radius: 3px;
|
||||
background:#222;
|
||||
color:#fff
|
||||
}
|
||||
.modal-header h4 {
|
||||
margin:0;
|
||||
@ -69,11 +68,16 @@
|
||||
->addClass('form-signin') !!}
|
||||
{{ Former::populateField('remember', 'true') }}
|
||||
|
||||
<div class="modal-header">
|
||||
<a href="{{ NINJA_WEB_URL }}" target="_blank">
|
||||
<div class="modal-header">
|
||||
@if (!isset($hideLogo) || !$hideLogo)
|
||||
<a href="{{ NINJA_WEB_URL }}" target="_blank">
|
||||
<img src="{{ asset('images/icon-login.png') }}" />
|
||||
<h4>Invoice Ninja | {{ trans('texts.account_login') }}</h4>
|
||||
</a>
|
||||
@else
|
||||
<h4>{{ trans('texts.account_login') }}</h4>
|
||||
</a>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
<div class="inner">
|
||||
<p>
|
||||
{!! Former::password('password')->placeholder(trans('texts.password'))->raw() !!}
|
||||
|
@ -1,10 +1,7 @@
|
||||
@extends('master')
|
||||
@extends('public.header')
|
||||
|
||||
@section('head')
|
||||
|
||||
<link href="{{ asset('css/bootstrap.min.css') }}" rel="stylesheet" type="text/css"/>
|
||||
<link href="{{ asset('css/style.css') }}" rel="stylesheet" type="text/css"/>
|
||||
|
||||
@parent
|
||||
<style type="text/css">
|
||||
body {
|
||||
padding-top: 40px;
|
||||
@ -13,6 +10,8 @@
|
||||
.modal-header {
|
||||
border-top-left-radius: 3px;
|
||||
border-top-right-radius: 3px;
|
||||
background:#222;
|
||||
color:#fff
|
||||
}
|
||||
.modal-header h4 {
|
||||
margin:0;
|
||||
@ -54,8 +53,16 @@
|
||||
<div class="container">
|
||||
|
||||
{!! Former::open('client/forgot')->addClass('form-signin') !!}
|
||||
<div class="modal-header">
|
||||
<h4>{{ trans('texts.password_recovery') }}</h4></div>
|
||||
<div class="modal-header">
|
||||
@if (!isset($hideLogo) || !$hideLogo)
|
||||
<a href="{{ NINJA_WEB_URL }}" target="_blank">
|
||||
<img src="{{ asset('images/icon-login.png') }}" />
|
||||
<h4>Invoice Ninja | {{ trans('texts.password_recovery') }}</h4>
|
||||
</a>
|
||||
@else
|
||||
<h4>{{ trans('texts.password_recovery') }}</h4>
|
||||
@endif
|
||||
</div>
|
||||
<div class="inner">
|
||||
|
||||
<p>{!! Button::success(trans('texts.send_email'))->large()->submit()->block() !!}</p>
|
||||
|
@ -1,10 +1,7 @@
|
||||
@extends('master')
|
||||
@extends('public.header')
|
||||
|
||||
@section('head')
|
||||
|
||||
<link href="{{ asset('css/bootstrap.min.css') }}" rel="stylesheet" type="text/css"/>
|
||||
<link href="{{ asset('css/style.css') }}" rel="stylesheet" type="text/css"/>
|
||||
|
||||
@parent
|
||||
<style type="text/css">
|
||||
body {
|
||||
padding-top: 40px;
|
||||
@ -13,6 +10,8 @@
|
||||
.modal-header {
|
||||
border-top-left-radius: 3px;
|
||||
border-top-right-radius: 3px;
|
||||
background:#222;
|
||||
color:#fff
|
||||
}
|
||||
.modal-header h4 {
|
||||
margin:0;
|
||||
@ -58,8 +57,16 @@
|
||||
'password_confirmation' => 'required',
|
||||
)) !!}
|
||||
|
||||
<div class="modal-header">
|
||||
<h4>{{ trans('texts.set_password') }}</h4></div>
|
||||
<div class="modal-header">
|
||||
@if (!isset($hideLogo) || !$hideLogo)
|
||||
<a href="{{ NINJA_WEB_URL }}" target="_blank">
|
||||
<img src="{{ asset('images/icon-login.png') }}" />
|
||||
<h4>Invoice Ninja | {{ trans('texts.set_password') }}</h4>
|
||||
</a>
|
||||
@else
|
||||
<h4>{{ trans('texts.set_password') }}</h4>
|
||||
@endif
|
||||
</div>
|
||||
<div class="inner">
|
||||
|
||||
<input type="hidden" name="token" value="{{{ $token }}}">
|
||||
|
Loading…
x
Reference in New Issue
Block a user