mirror of
https://github.com/firefly-iii/firefly-iii.git
synced 2025-01-13 09:32:48 -06:00
First version of routine #732
This commit is contained in:
parent
1878b5287b
commit
5d10a19bfa
@ -42,6 +42,7 @@ SHOW_INCOMPLETE_TRANSLATIONS=false
|
||||
CACHE_PREFIX=firefly
|
||||
|
||||
EXCHANGE_RATE_SERVICE=fixerio
|
||||
PASSWORD_SERVICE=false
|
||||
|
||||
GOOGLE_MAPS_API_KEY=
|
||||
ANALYTICS_ID=
|
||||
|
@ -17,6 +17,7 @@ use Config;
|
||||
use FireflyConfig;
|
||||
use FireflyIII\Events\RegisteredUser;
|
||||
use FireflyIII\Http\Controllers\Controller;
|
||||
use FireflyIII\Http\Requests\UserRegistrationRequest;
|
||||
use FireflyIII\User;
|
||||
use Illuminate\Foundation\Auth\RegistersUsers;
|
||||
use Illuminate\Http\Request;
|
||||
@ -56,7 +57,7 @@ class RegisterController extends Controller
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\Factory|\Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector|\Illuminate\View\View
|
||||
*/
|
||||
public function register(Request $request)
|
||||
public function register(UserRegistrationRequest $request)
|
||||
{
|
||||
// is allowed to?
|
||||
$singleUserMode = FireflyConfig::get('single_user_mode', Config::get('firefly.configuration.single_user_mode'))->data;
|
||||
|
@ -37,7 +37,7 @@ class ProfileFormRequest extends Request
|
||||
{
|
||||
return [
|
||||
'current_password' => 'required',
|
||||
'new_password' => 'required|confirmed',
|
||||
'new_password' => 'required|confirmed|secure_password',
|
||||
'new_password_confirmation' => 'required',
|
||||
];
|
||||
}
|
||||
|
53
app/Http/Requests/UserRegistrationRequest.php
Normal file
53
app/Http/Requests/UserRegistrationRequest.php
Normal file
@ -0,0 +1,53 @@
|
||||
<?php
|
||||
/**
|
||||
* UserRegistrationRequest.php
|
||||
* Copyright (c) 2017 thegrumpydictator@gmail.com
|
||||
* This software may be modified and distributed under the terms of the Creative Commons Attribution-ShareAlike 4.0 International License.
|
||||
*
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Http\Requests;
|
||||
|
||||
/**
|
||||
* Class UserRegistrationRequest
|
||||
*
|
||||
*
|
||||
* @package FireflyIII\Http\Requests
|
||||
*/
|
||||
class UserRegistrationRequest extends Request
|
||||
{
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
// Only everybody
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getUserData(): array
|
||||
{
|
||||
return [
|
||||
'email' => $this->string('email'),
|
||||
'password' => $this->string('password'),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'email' => 'email|required',
|
||||
'password' => 'confirmed|secure_password',
|
||||
|
||||
];
|
||||
}
|
||||
}
|
@ -39,6 +39,8 @@ use FireflyIII\Support\Amount;
|
||||
use FireflyIII\Support\ExpandedForm;
|
||||
use FireflyIII\Support\FireflyConfig;
|
||||
use FireflyIII\Support\Navigation;
|
||||
use FireflyIII\Support\Password\PwndVerifier;
|
||||
use FireflyIII\Support\Password\Verifier;
|
||||
use FireflyIII\Support\Preferences;
|
||||
use FireflyIII\Support\Steam;
|
||||
use FireflyIII\Support\Twig\AmountFormat;
|
||||
@ -147,6 +149,9 @@ class FireflyServiceProvider extends ServiceProvider
|
||||
$this->app->bind(FiscalHelperInterface::class, FiscalHelper::class);
|
||||
$this->app->bind(BalanceReportHelperInterface::class, BalanceReportHelper::class);
|
||||
$this->app->bind(BudgetReportHelperInterface::class, BudgetReportHelper::class);
|
||||
|
||||
// password verifier thing
|
||||
$this->app->bind(Verifier::class, PwndVerifier::class);
|
||||
}
|
||||
|
||||
}
|
||||
|
51
app/Support/Password/PwndVerifier.php
Normal file
51
app/Support/Password/PwndVerifier.php
Normal file
@ -0,0 +1,51 @@
|
||||
<?php
|
||||
/**
|
||||
* PwndVerifier.php
|
||||
* Copyright (c) 2017 thegrumpydictator@gmail.com
|
||||
* This software may be modified and distributed under the terms of the Creative Commons Attribution-ShareAlike 4.0 International License.
|
||||
*
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Support\Password;
|
||||
|
||||
use Log;
|
||||
use Requests;
|
||||
use Requests_Exception;
|
||||
|
||||
/**
|
||||
* Class PwndVerifier
|
||||
*
|
||||
* @package FireflyIII\Support\Password
|
||||
*/
|
||||
class PwndVerifier implements Verifier
|
||||
{
|
||||
|
||||
/**
|
||||
* Verify the given password against (some) service.
|
||||
*
|
||||
* @param string $password
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function validPassword(string $password): bool
|
||||
{
|
||||
$hash = sha1($password);
|
||||
$uri = sprintf('https://haveibeenpwned.com/api/v2/pwnedpassword/%s', $hash);
|
||||
$opt = ['useragent' => 'Firefly III v' . config('firefly.version'), 'timeout' => 2];
|
||||
|
||||
try {
|
||||
$result = Requests::get($uri, ['originalPasswordIsAHash' => 'true'], $opt);
|
||||
} catch (Requests_Exception $e) {
|
||||
return true;
|
||||
}
|
||||
Log::debug(sprintf('Status code returned is %d', $result->status_code));
|
||||
if ($result->status_code === 404) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
29
app/Support/Password/Verifier.php
Normal file
29
app/Support/Password/Verifier.php
Normal file
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
/**
|
||||
* Verifier.php
|
||||
* Copyright (c) 2017 thegrumpydictator@gmail.com
|
||||
* This software may be modified and distributed under the terms of the Creative Commons Attribution-ShareAlike 4.0 International License.
|
||||
*
|
||||
* See the LICENSE file for details.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace FireflyIII\Support\Password;
|
||||
|
||||
/**
|
||||
* Interface Verifier
|
||||
*
|
||||
* @package FireflyIII\Support\Password
|
||||
*/
|
||||
interface Verifier
|
||||
{
|
||||
/**
|
||||
* Verify the given password against (some) service.
|
||||
* @param string $password
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function validPassword(string $password): bool;
|
||||
|
||||
}
|
@ -24,11 +24,15 @@ use FireflyIII\Models\PiggyBank;
|
||||
use FireflyIII\Models\TransactionType;
|
||||
use FireflyIII\Repositories\Budget\BudgetRepositoryInterface;
|
||||
use FireflyIII\Rules\Triggers\TriggerInterface;
|
||||
use FireflyIII\Support\Password\Verifier;
|
||||
use FireflyIII\User;
|
||||
use Google2FA;
|
||||
use Illuminate\Contracts\Encryption\DecryptException;
|
||||
use Illuminate\Contracts\Translation\Translator;
|
||||
use Illuminate\Validation\Validator;
|
||||
use Log;
|
||||
use Requests;
|
||||
use Requests_Exception;
|
||||
|
||||
/**
|
||||
* Class FireflyValidator
|
||||
@ -274,6 +278,24 @@ class FireflyValidator extends Validator
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $attribute
|
||||
* @param $value
|
||||
* @param $parameters
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function validateSecurePassword($attribute, $value, $parameters): bool
|
||||
{
|
||||
$enabled = env('PASSWORD_SERVICE');
|
||||
if (!$enabled) {
|
||||
return true;
|
||||
}
|
||||
/** @var Verifier $service */
|
||||
$service = app(Verifier::class);
|
||||
return $service->validPassword($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
||||
* @param $attribute
|
||||
|
@ -88,4 +88,5 @@ return [
|
||||
'in_array' => 'The :attribute field does not exist in :other.',
|
||||
'present' => 'The :attribute field must be present.',
|
||||
'amount_zero' => 'The total amount cannot be zero',
|
||||
'secure_password' => 'This is not a secure password. Please try again. For more information, visit https://goo.gl/NCh2tN',
|
||||
];
|
||||
|
@ -1,38 +0,0 @@
|
||||
{% extends "./layout/default" %}
|
||||
|
||||
{% block breadcrumbs %}
|
||||
{{ Breadcrumbs.renderIfExists }}
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
<div class="row">
|
||||
<div class="col-lg-12 col-md-12 col-sm-12">
|
||||
<div class="box box-default">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">{{ 'import_finished'|_ }}</h3>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<p>
|
||||
{{ 'import_finished_intro'|_ }}
|
||||
</p>
|
||||
{% if tagId > 0 %}
|
||||
<p>
|
||||
{{ trans('firefly.import_finished_text_with_link', {tag: tagId})|raw }}
|
||||
</p>
|
||||
{% else %}
|
||||
<p>
|
||||
{{ 'import_finished_text_without_link'|_ }}
|
||||
</p>
|
||||
{% endif %}
|
||||
|
||||
<p>
|
||||
{{ 'import_share_configuration'|_ }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
{% block scripts %}
|
||||
{% endblock %}
|
||||
{% block styles %}
|
||||
{% endblock %}
|
@ -1,157 +0,0 @@
|
||||
{% extends "./layout/default" %}
|
||||
|
||||
{% block breadcrumbs %}
|
||||
{{ Breadcrumbs.renderIfExists }}
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
|
||||
{# Initial display. Will refresh (and disappear almost immediately. #}
|
||||
|
||||
<div class="row status_initial statusbox">
|
||||
<div class="col-lg-8 col-lg-offset-2 col-md-12 col-sm-12">
|
||||
<div class="box box-primary">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">{{ 'import_status_wait_title'|_ }}</h3>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<p>
|
||||
{{ 'import_status_wait_text'|_ }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{# Fatal error display. Will be shown (duh) when something goes horribly wrong. #}
|
||||
<div class="row fatal_error" style="display:none;">
|
||||
<div class="col-lg-8 col-lg-offset-2 col-md-12 col-sm-12">
|
||||
<div class="box box-danger">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">{{ 'import_status_fatal_title'|_ }}</h3>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<p>
|
||||
{{ 'import_status_fatal_text'|_ }}
|
||||
</p>
|
||||
<p class="text-danger fatal_error_txt">
|
||||
|
||||
</p>
|
||||
<p>
|
||||
{{ 'import_status_fatal_more'|_ }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{# Box for when the job is ready to start #}
|
||||
<div class="row status_configured statusbox" style="display:none;">
|
||||
<div class="col-lg-8 col-lg-offset-2 col-md-12 col-sm-12">
|
||||
<div class="box box-primary">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">{{ 'import_status_ready_title'|_ }}</h3>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<p>
|
||||
{{ 'import_status_ready_text'|_ }}
|
||||
</p>
|
||||
<p>
|
||||
<code>php artisan firefly:start-import {{ job.key }}</code>
|
||||
</p>
|
||||
<div class="row">
|
||||
<div class="col-lg-4">
|
||||
<a href="{{ route('import.download', [job.key]) }}" class="btn btn-default"><i
|
||||
class="fa fa-fw fa-download"></i> {{ 'import_status_ready_config'|_ }}</a>
|
||||
</div>
|
||||
<div class="col-lg-4">
|
||||
<button class="btn btn-success start-job"><i class="fa fa-fw fa-gears"></i> {{ 'import_status_ready_start'|_ }}</button>
|
||||
</div>
|
||||
</div>
|
||||
<p>
|
||||
|
||||
</p>
|
||||
<p class="text-info">
|
||||
{{ 'import_status_ready_share'|_ }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{# Box for when the job is running! #}
|
||||
<div class="row status_running statusbox" style="display: none;">
|
||||
<div class="col-lg-8 col-lg-offset-2 col-md-12 col-sm-12">
|
||||
<div class="box box-primary">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title" id="import-status-title">{{ 'import_status_running_title'|_ }}</h3>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<div id="import-status-holder">
|
||||
<div class="progress" id="import-status-holder">
|
||||
<div id="import-status-bar" class="progress-bar progress-bar-info active progress-bar-striped" role="progressbar"
|
||||
aria-valuenow="100" aria-valuemin="0"
|
||||
aria-valuemax="100" style="width: 100%;min-width:40px;">
|
||||
</div>
|
||||
</div>
|
||||
<p id="import-status-txt">{{ 'import_status_running_placeholder'|_ }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{# displays the finished status of the import. #}
|
||||
<div class="row status_finished statusbox" style="display:none;">
|
||||
<div class="col-lg-8 col-lg-offset-2 col-md-12 col-sm-12">
|
||||
<div class="box box-default">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">{{ 'import_status_finished_title'|_ }}</h3>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<p id="import-status-intro">
|
||||
{{ 'import_status_finished_text'|_ }}
|
||||
</p>
|
||||
<p id="import-status-more-info"></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{# box to show error information. #}
|
||||
<div class="row info_errors" style="display:none;">
|
||||
<div class="col-lg-8 col-lg-offset-2 col-md-12 col-sm-12">
|
||||
<div class="box box-danger">
|
||||
<div class="box-header with-border">
|
||||
<h3 class="box-title">{{ 'import_status_errors_title'|_ }}</h3>
|
||||
</div>
|
||||
<div class="box-body">
|
||||
<p id="import-status-error-intro">
|
||||
</p>
|
||||
<div id="import-status-error-list"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
{% block scripts %}
|
||||
<script type="text/javascript">
|
||||
|
||||
// some useful translations.
|
||||
var langImportSingleError = '{{ 'import_status_errors_single'|_|escape }}';
|
||||
var langImportMultiError = '{{ 'import_status_errors_multi'|_|escape }}';
|
||||
|
||||
//var langImportFatalError = '{{ 'import_error_fatal'|_|escape }}';
|
||||
//var langImportTimeOutError = '{{ 'import_error_timeout'|_|escape }}';
|
||||
//var langImportFinished = '{{ 'import_finished_all'|_|escape }}';
|
||||
|
||||
|
||||
var jobKey = '{{ job.key }}';
|
||||
var jobImportUrl = '{{ route('import.json', [job.key]) }}';
|
||||
var jobStartUrl = '{{ route('import.start', [job.key]) }}';
|
||||
var token = '{{ csrf_token() }}';
|
||||
</script>
|
||||
<script type="text/javascript" src="js/ff/import/status.js"></script>
|
||||
{% endblock %}
|
||||
{% block styles %}
|
||||
{% endblock %}
|
Loading…
Reference in New Issue
Block a user