From 73e38a006ed127d49d46eb19eefe74085d135874 Mon Sep 17 00:00:00 2001 From: Kevin Adametz Date: Tue, 9 Nov 2021 18:38:44 +0100 Subject: [PATCH] Google2Fa ready to upload --- app/Exceptions/Handler.php | 16 +- .../Controllers/Admin/ReportController.php | 2 +- app/Http/Controllers/AdminUserController.php | 116 ++++++-- app/Http/Controllers/Auth/LoginController.php | 23 +- app/Http/Controllers/BookingController.php | 5 +- .../CMS/CMSAnswerQuestionController.php | 2 + .../Controllers/CMS/CMSBookingController.php | 19 +- .../CMS/CMSContentAuthorController.php | 1 + .../Controllers/CMS/CMSContentController.php | 2 +- .../CMS/CMSContentInfoController.php | 2 + .../Controllers/CMS/CMSFeWoController.php | 2 + .../Controllers/CMS/CMSFeedbackController.php | 2 + .../Controllers/CMS/CMSSidebarController.php | 1 + .../CMS/CMSTravelGuideController.php | 1 + app/Http/Controllers/CronController.php | 2 - app/Http/Controllers/CustomerController.php | 2 +- .../CustomerFewoMailController.php | 2 +- .../Controllers/CustomerMailController.php | 4 +- app/Http/Controllers/DraftController.php | 3 +- .../Controllers/IQ/ContentModalController.php | 2 +- .../Controllers/IQ/ContentTreeController.php | 2 +- .../IQ/Tools/ContentLinkController.php | 2 +- .../Controllers/IQ/TravelGroupController.php | 2 +- .../Controllers/IQ/TravelItemController.php | 2 +- .../IQ/TravelProgrammController.php | 2 +- app/Http/Controllers/LeadController.php | 8 +- app/Http/Controllers/LeadMailController.php | 2 +- app/Http/Controllers/MailController.php | 110 ++++--- app/Http/Controllers/ModalController.php | 14 +- app/Http/Controllers/RequestController.php | 9 +- .../Settings/AirlineController.php | 3 +- .../Settings/BookingStatusController.php | 2 +- .../Settings/CategoryController.php | 2 +- .../Controllers/Settings/EmailsController.php | 8 +- .../Settings/InsuranceController.php | 2 +- .../Settings/KeywordController.php | 3 +- .../Settings/ServiceProviderController.php | 2 +- .../Settings/TravelAgendaController.php | 3 +- .../Settings/TravelCompanyController.php | 2 +- .../Settings/TravelCountryController.php | 3 +- .../Settings/TravelNationalityController.php | 4 +- .../Settings/TravelPlaceController.php | 5 +- .../SyS/Tools/ContentLinkController.php | 2 +- .../Controllers/TravelProgramController.php | 2 +- .../TravelUserBookingFewoController.php | 6 +- app/Http/Controllers/TravelUserController.php | 3 +- app/Http/Kernel.php | 3 +- app/Http/Middleware/AuthGoogle2FA.php | 24 ++ app/Http/Middleware/Authenticate.php | 99 +++++++ app/Http/Middleware/Google2FA.php | 24 ++ app/Http/Middleware/Google2FAAuth.php | 25 ++ app/Http/Middleware/MiddleGoogle2FA.php | 24 ++ app/Models/Airline.php | 6 + app/Models/Booking.php | 5 + app/Models/Branch.php | 12 +- app/Models/CMSContent.php | 16 ++ app/Models/CMSInfo.php | 1 + app/Models/IQContentCategory.php | 1 + app/Models/IQContentTree.php | 1 + app/Models/IQContentTreeNode.php | 1 + app/Models/IQTravelGroup.php | 22 +- app/Models/IQTravelGroupItem.php | 14 +- app/Models/IQTravelItem.php | 26 +- app/Models/IQTravelItemPlace.php | 14 +- app/Models/IQTravelProgram.php | 28 +- app/Models/IQTravelProgramItem.php | 17 +- app/Models/Lead.php | 9 + app/Models/LeadFile.php | 20 +- app/Models/LeadMail.php | 34 ++- app/Models/LeadNotice.php | 20 +- app/Models/LeadParticipant.php | 5 + app/Models/Participant.php | 11 +- app/Models/SfGuardUser.php | 1 + app/Models/Sym/CmsContent.php | 1 + app/Models/Sym/TravelCountry.php | 2 + app/Models/TravelCountry.php | 11 + app/Models/TravelGuide.php | 1 + app/Models/TravelPlace.php | 17 +- app/Models/TravelUserBookingFewo.php | 2 + app/Models/TravelUserBookingFewoNotice.php | 20 +- app/Repositories/BookingRepository.php | 2 +- app/Repositories/CustomerMailRepository.php | 1 - app/Repositories/LeadMailRepository.php | 2 +- app/Services/AuthGoogle2FA.php | 235 +++++++++++++++ app/Services/Google2FA.php | 127 +++++++++ app/Services/HTMLHelper.php | 2 +- app/Services/MyGoogle2FA.php | 105 +++++++ app/Services/Placeholder.php | 51 +++- app/User.php | 29 +- bootstrap/cache/packages.php | 54 ++++ bootstrap/cache/services.php | 150 ++++++---- composer.json | 48 ++-- config/google2fa.php | 83 ++++++ .../2014_10_12_000000_create_users_table.php | 2 + ..._01_29_152709_create_participant_table.php | 3 +- .../laravel-filemanager/composer.json | 13 +- public/js/custom.js | 40 --- .../js/summernote-iq-content-placeholders.js | 269 ++++++++++++++++++ public/js/summernote-placeholders.js | 112 ++++++++ resources/lang/de/validation.php | 1 + resources/views/admin/active_modal.blade.php | 31 ++ .../views/admin/google2fa__modal.blade.php | 60 ++++ .../admin/google2fa_delete_modal.blade.php | 35 +++ .../views/admin/google2fa_modal.blade.php | 41 +++ .../modal/cms_booking_content_edit.blade.php | 57 ++++ resources/views/admin/user_form.blade.php | 8 - resources/views/admin/user_modal.blade.php | 12 +- resources/views/admin/users.blade.php | 44 ++- resources/views/auth/google2fa.blade.php | 58 ++++ .../views/auth/google2fa_activate.blade.php | 73 +++++ .../booking/_detail_participant.blade.php | 7 + .../views/cms/booking/all/detail.blade.php | 167 +++++++---- .../cms/booking/content/detail.blade.php | 186 ++++++++---- .../views/cms/booking/content/index.blade.php | 70 ++--- resources/views/cms/fewo/all/index.blade.php | 2 +- .../views/cms/fewo/content/detail.blade.php | 2 +- .../mail/modal-show-mail-inner.blade.php | 4 + resources/views/layouts/application.blade.php | 2 - .../lead/modal-show-mail-inner.blade.php | 6 +- resources/views/mails/booking.blade.php | 6 +- resources/views/mails/booking_fewo.blade.php | 6 +- resources/views/mails/lead.blade.php | 6 +- resources/views/request/index.blade.php | 29 +- .../mail/modal-show-mail-inner.blade.php | 6 +- routes/web.php | 47 +-- storage/app/google2fasecret.key | 1 + .../Einreisebestimmungen_de_de-MA.pdf | Bin 0 -> 48561 bytes 127 files changed, 2637 insertions(+), 589 deletions(-) create mode 100644 app/Http/Middleware/AuthGoogle2FA.php create mode 100644 app/Http/Middleware/Authenticate.php create mode 100644 app/Http/Middleware/Google2FA.php create mode 100644 app/Http/Middleware/Google2FAAuth.php create mode 100644 app/Http/Middleware/MiddleGoogle2FA.php create mode 100644 app/Services/AuthGoogle2FA.php create mode 100644 app/Services/Google2FA.php create mode 100644 app/Services/MyGoogle2FA.php create mode 100644 config/google2fa.php create mode 100644 public/js/summernote-iq-content-placeholders.js create mode 100644 public/js/summernote-placeholders.js create mode 100644 resources/views/admin/active_modal.blade.php create mode 100644 resources/views/admin/google2fa__modal.blade.php create mode 100644 resources/views/admin/google2fa_delete_modal.blade.php create mode 100644 resources/views/admin/google2fa_modal.blade.php create mode 100644 resources/views/admin/modal/cms_booking_content_edit.blade.php create mode 100644 resources/views/auth/google2fa.blade.php create mode 100644 resources/views/auth/google2fa_activate.blade.php create mode 100644 storage/app/google2fasecret.key create mode 100644 storage/app/public/pdf/passolution/Einreisebestimmungen_de_de-MA.pdf diff --git a/app/Exceptions/Handler.php b/app/Exceptions/Handler.php index 043cad6..59c585d 100755 --- a/app/Exceptions/Handler.php +++ b/app/Exceptions/Handler.php @@ -2,8 +2,8 @@ namespace App\Exceptions; -use Exception; use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler; +use Throwable; class Handler extends ExceptionHandler { @@ -29,10 +29,12 @@ class Handler extends ExceptionHandler /** * Report or log an exception. * - * @param \Exception $exception + * @param \Throwable $exception * @return void + * + * @throws \Exception */ - public function report(Exception $exception) + public function report(Throwable $exception) { parent::report($exception); } @@ -41,10 +43,12 @@ class Handler extends ExceptionHandler * Render an exception into an HTTP response. * * @param \Illuminate\Http\Request $request - * @param \Exception $exception - * @return \Illuminate\Http\Response + * @param \Throwable $exception + * @return \Symfony\Component\HttpFoundation\Response + * + * @throws \Throwable */ - public function render($request, Exception $exception) + public function render($request, Throwable $exception) { return parent::render($request, $exception); } diff --git a/app/Http/Controllers/Admin/ReportController.php b/app/Http/Controllers/Admin/ReportController.php index 7b8d11a..976af2b 100755 --- a/app/Http/Controllers/Admin/ReportController.php +++ b/app/Http/Controllers/Admin/ReportController.php @@ -22,7 +22,7 @@ class ReportController extends Controller { public function __construct() { - $this->middleware('superadmin'); + $this->middleware(['superadmin', '2fa']); } public function bookings() diff --git a/app/Http/Controllers/AdminUserController.php b/app/Http/Controllers/AdminUserController.php index 3d0e55f..9e6b4e7 100755 --- a/app/Http/Controllers/AdminUserController.php +++ b/app/Http/Controllers/AdminUserController.php @@ -4,15 +4,16 @@ namespace App\Http\Controllers; -use App\Mail\MailVerifyContact; -use App\Models\Account; -use App\Repositories\UserRepository; -use App\Services\HTMLHelper; -use App\User; -use Illuminate\Support\Facades\Mail; use Request; +use App\User; use Validator; use DataTables; +use App\Models\Account; +use App\Services\HTMLHelper; +use App\Services\MyGoogle2FA; +use App\Mail\MailVerifyContact; +use App\Repositories\UserRepository; +use Illuminate\Support\Facades\Mail; class AdminUserController extends Controller { @@ -20,9 +21,8 @@ class AdminUserController extends Controller public function __construct(UserRepository $userRepo) { - $this->middleware('superadmin'); + $this->middleware(['superadmin', '2fa']); $this->userRepo = $userRepo; - } /** @@ -34,6 +34,12 @@ class AdminUserController extends Controller //'values' => User::where('admin', 0)->get(), 'values' => User::where('confirmation_code_remider', '!=', 2)->get(), ]; + $user = User::findOrFail(8); + + /* $MyGoogle2FA = new MyGoogle2FA(); + $valid = $MyGoogle2FA->init($user)->check2Fa('676493'); + dd($valid); */ + return view('admin.users', $data); } @@ -121,40 +127,97 @@ class AdminUserController extends Controller public function loadModal($id){ if(Request::ajax()) { + $data = Request::all(); $user = User::findOrFail($id); + if(isset($data['action'])){ + if($data['action'] === 'show-user-roles'){ + $fill = [ + 'user' => $user, + 'action' => $data['action'], + 'groups' => config('permissions.groups'), + 'roles' => config('permissions.roles') + ]; + return view("admin.user_modal", $fill )->render(); + } + if($data['action'] === 'show-user-active'){ + $fill = [ + 'user' => $user, + 'action' => $data['action'], + ]; + return view("admin.active_modal", $fill )->render(); + } + - $data = [ - 'user' => $user, - 'groups' => config('permissions.groups'), - 'roles' => config('permissions.roles') - ]; - return view("admin.user_modal", $data )->render(); + if($data['action'] === 'show-user-google2fa'){ + + if($user->isGoogle2Fa()){ + $MyGoogle2FA = new MyGoogle2FA(); + $MyGoogle2FA->init($user); + $fill = [ + 'user' => $user, + 'action' => 'delete-user-google2fa', + 'MyGoogle2FA' => $MyGoogle2FA, + ]; + return view("admin.google2fa_delete_modal", $fill )->render(); + }else{ + $MyGoogle2FA = new MyGoogle2FA(); + $MyGoogle2FA->init($user)->generate(); + $fill = [ + 'user' => $user, + 'action' => 'activate-user-google2fa', + 'MyGoogle2FA' => $MyGoogle2FA, + ]; + return view("admin.google2fa_modal", $fill )->render(); + } + } + } } return false; } - public function updateModal($step = false){ + public function updateModal($action = false){ - if($step == 'user'){ + if($action=== 'show-user-roles'){ $data = Request::all(); $user = User::findOrFail($data['id']); - $user->permissions = isset($data['permissions']) ? $data['permissions'] : []; $user->admin = $data['admin']; $user->confirmed = isset($data['confirmed']) ? true : false; $user->active = isset($data['active']) ? true : false; $user->save(); + \Session()->flash('alert-save', true); } + if($action=== 'show-user-active'){ + $data = Request::all(); + $user = User::findOrFail($data['id']); + $user->active = isset($data['active']) ? true : false; + $user->save(); + \Session()->flash('alert-save', true); + + } + if($action=== 'activate-user-google2fa'){ + $data = Request::all(); + $user = User::findOrFail($data['id']); + $user->google2fa = true; + $user->save(); + \Session()->flash('alert-save', true); + } + + if($action=== 'delete-user-google2fa'){ + $data = Request::all(); + $user = User::findOrFail($data['id']); + $user->google2fa = false; + $user->secret_key = null; + $user->save(); + \Session()->flash('alert-save', true); + } - \Session()->flash('alert-save', true); return redirect('/admin/users'); } - -// public function getUsers() { //confirmation_code_remider is delete 2 @@ -165,13 +228,20 @@ class AdminUserController extends Controller return ''; }) ->addColumn('admin', function (User $user) { - return ''.HTMLHelper::getRoleLabel($user->admin, ' Rechte + ','').''; + return ''.HTMLHelper::getRoleLabel($user->admin, ' Rechte + ','').''; + }) + ->addColumn('google2fa', function (User $user) { + $icon = $user->google2fa ? '' : ''; + $color = $user->google2fa ? 'primary' : 'danger'; + return ' '.$icon.' google2fa'; }) ->addColumn('confirmed', function (User $user) { return $user->confirmed ? '' : ''; }) ->addColumn('active', function (User $user) { - return $user->active ? ' ' : ''; + $active = $user->active ? '' : ''; + return ' '.$active.''; + }) ->addColumn('action_delete', function (User $user) { return ''; @@ -179,7 +249,7 @@ class AdminUserController extends Controller ->orderColumn('confirmed', 'confirmed $1') ->orderColumn('active', 'active $1') ->orderColumn('admin', 'active $1') - ->rawColumns(['action_edit', 'admin', 'confirmed', 'active', 'action_delete']) + ->rawColumns(['action_edit', 'admin', 'confirmed', 'active', 'action_delete', 'google2fa']) ->make(true); } diff --git a/app/Http/Controllers/Auth/LoginController.php b/app/Http/Controllers/Auth/LoginController.php index cf40ac0..aae22e6 100755 --- a/app/Http/Controllers/Auth/LoginController.php +++ b/app/Http/Controllers/Auth/LoginController.php @@ -52,18 +52,15 @@ class LoginController extends Controller } + protected function validateLogin(Request $request) + { + $this->validate($request, [ + $this->username() => 'required|exists:users,' . $this->username() . ',active,1', + 'password' => 'required', + ], [ + $this->username() . '.exists' => trans('validation.usernotactive'), + ]); - //* - // - /* protected function validateLogin(Request $request) - { - $this->validate($request, [ - $this->username() => 'required|exists:users,' . $this->username() . ',active,1', - 'password' => 'required', - ], [ - $this->username() . '.exists' => trans('validation.usernotactive'), - ]); - - } - */ + + } } diff --git a/app/Http/Controllers/BookingController.php b/app/Http/Controllers/BookingController.php index 6b51f24..b91403d 100755 --- a/app/Http/Controllers/BookingController.php +++ b/app/Http/Controllers/BookingController.php @@ -4,7 +4,6 @@ namespace App\Http\Controllers; use Request; use App\Models\Booking; -use App\Models\Customer; use App\Models\BookingFile; use App\Models\BookingNotice; use App\Models\ServiceProvider; @@ -24,8 +23,8 @@ class BookingController extends Controller protected $bookingRepo; public function __construct(BookingRepository $bookingRepo) - { - $this->middleware('admin'); + { + $this->middleware(['admin', '2fa']); $this->bookingRepo = $bookingRepo; } diff --git a/app/Http/Controllers/CMS/CMSAnswerQuestionController.php b/app/Http/Controllers/CMS/CMSAnswerQuestionController.php index 15e7a73..14c6a93 100755 --- a/app/Http/Controllers/CMS/CMSAnswerQuestionController.php +++ b/app/Http/Controllers/CMS/CMSAnswerQuestionController.php @@ -23,6 +23,8 @@ class CMSAnswerQuestionController extends Controller public function __construct() { + $this->middleware(['admin', '2fa']); + $this->identifier_options = IQContentCategory::where('identifier', 'faq') ->where('active', true) ->orderBy('pos', 'ASC') diff --git a/app/Http/Controllers/CMS/CMSBookingController.php b/app/Http/Controllers/CMS/CMSBookingController.php index c2aced9..6ce0e45 100644 --- a/app/Http/Controllers/CMS/CMSBookingController.php +++ b/app/Http/Controllers/CMS/CMSBookingController.php @@ -24,6 +24,8 @@ class CMSBookingController extends Controller public function __construct() { + $this->middleware(['admin', '2fa']); + $this->identifier_general_name = config('booking.identifier_general_name'); $this->identifier_content_name = config('booking.identifier_content_name'); $this->identifier_general = config('booking.identifier_general'); @@ -78,12 +80,11 @@ class CMSBookingController extends Controller } } - if($data['action'] === 'addItem'){ $general_name = CMSContent::findOrFail($id); $identifier_general = $this->identifier_general.$general_name->id; $create = [ - 'name' => 'Abschnitt', + 'name' => '#empty#', 'field' => 'full_text', 'decimal' => 1, 'identifier' => $identifier_general, @@ -102,6 +103,8 @@ class CMSBookingController extends Controller foreach ($data['contents'] as $content_id => $item) { $content = CMSContent::findOrFail($content_id); $content->setObjectBy('page-break', (isset($item['page-break']) ? true : false)); + $content->setObjectBy('repeat-country', (isset($item['repeat-country']) ? true : false)); + $content->setObjectBy('repeat-airline', (isset($item['repeat-airline']) ? true : false)); $content->name = $item['name']; $content->slug = null; $content->decimal = isset($item['in_pdf']) ? 1 : 0; @@ -121,7 +124,13 @@ class CMSBookingController extends Controller public function deleteAll($id, $do){ if($do === 'name'){ $general_name = CMSContent::findOrFail($id); + $find = CMSContent::findObjectsBy('general_id', $general_name->id); + if(count($find)){ + \Session()->flash('alert-error', __('Vorlage kann nicht gelöscht werden, ist bei den Inhalten noch in Verwendung.')); + return back(); + } $identifier_general = $this->identifier_general.$general_name->id; + //check is use $contents = CMSContent::where('identifier', '=', $identifier_general)->get(); foreach($contents as $con){ $con->delete(); @@ -206,7 +215,7 @@ class CMSBookingController extends Controller if($data['action'] === 'addItem' && isset($data['content_pos_id'])) { $create = [ - 'name' => 'Abschnitt', + 'name' => '#empty#', 'field' => 'full_text', 'decimal' => 1, 'integer' => $data['content_pos_id'], @@ -220,8 +229,6 @@ class CMSBookingController extends Controller return redirect(route('cms_booking_content_detail', [$id])); } - - if($data['action'] === 'saveAll'){ $i = 1; $last_content_id = null; @@ -233,6 +240,8 @@ class CMSBookingController extends Controller } if ($item['identifier'] === $identifier_content) { $content->setObjectBy('page-break', (isset($item['page-break']) ? true : false)); + $content->setObjectBy('repeat-country', (isset($item['repeat-country']) ? true : false)); + $content->setObjectBy('repeat-airline', (isset($item['repeat-airline']) ? true : false)); $content->name = $item['name']; $content->slug = null; $content->decimal = isset($item['in_pdf']) ? 1 : 0; diff --git a/app/Http/Controllers/CMS/CMSContentAuthorController.php b/app/Http/Controllers/CMS/CMSContentAuthorController.php index 38296ca..5170c74 100755 --- a/app/Http/Controllers/CMS/CMSContentAuthorController.php +++ b/app/Http/Controllers/CMS/CMSContentAuthorController.php @@ -19,6 +19,7 @@ class CMSContentAuthorController extends Controller */ public function __construct() { + $this->middleware(['admin', '2fa']); } diff --git a/app/Http/Controllers/CMS/CMSContentController.php b/app/Http/Controllers/CMS/CMSContentController.php index 49e02b7..2e65d0f 100755 --- a/app/Http/Controllers/CMS/CMSContentController.php +++ b/app/Http/Controllers/CMS/CMSContentController.php @@ -17,8 +17,8 @@ class CMSContentController extends Controller public function __construct() { + $this->middleware(['admin', '2fa']); $this->identifier_content = 'general'; - } diff --git a/app/Http/Controllers/CMS/CMSContentInfoController.php b/app/Http/Controllers/CMS/CMSContentInfoController.php index 736370c..74281fd 100755 --- a/app/Http/Controllers/CMS/CMSContentInfoController.php +++ b/app/Http/Controllers/CMS/CMSContentInfoController.php @@ -23,6 +23,8 @@ class CMSContentInfoController extends Controller */ public function __construct() { + $this->middleware(['admin', '2fa']); + } public function index() diff --git a/app/Http/Controllers/CMS/CMSFeWoController.php b/app/Http/Controllers/CMS/CMSFeWoController.php index e688a0d..f0fc0ee 100755 --- a/app/Http/Controllers/CMS/CMSFeWoController.php +++ b/app/Http/Controllers/CMS/CMSFeWoController.php @@ -21,6 +21,8 @@ class CMSFeWoController extends Controller public function __construct() { + $this->middleware(['admin', '2fa']); + $this->identifier_content = config('fewo.identifier_content'); $this->identifier_fewo = config('fewo.identifier_fewo'); } diff --git a/app/Http/Controllers/CMS/CMSFeedbackController.php b/app/Http/Controllers/CMS/CMSFeedbackController.php index 103173e..676fcc4 100755 --- a/app/Http/Controllers/CMS/CMSFeedbackController.php +++ b/app/Http/Controllers/CMS/CMSFeedbackController.php @@ -18,6 +18,8 @@ class CMSFeedbackController extends Controller */ public function __construct() { + $this->middleware(['admin', '2fa']); + } diff --git a/app/Http/Controllers/CMS/CMSSidebarController.php b/app/Http/Controllers/CMS/CMSSidebarController.php index 0e7e796..db03885 100755 --- a/app/Http/Controllers/CMS/CMSSidebarController.php +++ b/app/Http/Controllers/CMS/CMSSidebarController.php @@ -18,6 +18,7 @@ class CMSSidebarController extends Controller */ public function __construct() { + $this->middleware(['admin', '2fa']); } /** diff --git a/app/Http/Controllers/CMS/CMSTravelGuideController.php b/app/Http/Controllers/CMS/CMSTravelGuideController.php index 311e503..c0af249 100755 --- a/app/Http/Controllers/CMS/CMSTravelGuideController.php +++ b/app/Http/Controllers/CMS/CMSTravelGuideController.php @@ -24,6 +24,7 @@ class CMSTravelGuideController extends Controller */ public function __construct() { + $this->middleware(['admin', '2fa']); } public function index() diff --git a/app/Http/Controllers/CronController.php b/app/Http/Controllers/CronController.php index ee89966..7ad4958 100644 --- a/app/Http/Controllers/CronController.php +++ b/app/Http/Controllers/CronController.php @@ -22,8 +22,6 @@ class CronController extends Controller public function __construct(UserRepository $userRepo) { $this->userRepo = $userRepo; - - // $this->middleware('auth'); } public function index() diff --git a/app/Http/Controllers/CustomerController.php b/app/Http/Controllers/CustomerController.php index f3d0151..54129ef 100755 --- a/app/Http/Controllers/CustomerController.php +++ b/app/Http/Controllers/CustomerController.php @@ -14,7 +14,7 @@ class CustomerController extends Controller public function __construct(CustomerRepository $custRepo) { - $this->middleware('admin'); + $this->middleware(['admin', '2fa']); $this->custRepo = $custRepo; } diff --git a/app/Http/Controllers/CustomerFewoMailController.php b/app/Http/Controllers/CustomerFewoMailController.php index b169304..434ee5a 100755 --- a/app/Http/Controllers/CustomerFewoMailController.php +++ b/app/Http/Controllers/CustomerFewoMailController.php @@ -25,7 +25,7 @@ class CustomerFewoMailController extends Controller public function __construct(CustomerFewoMailRepository $customerMailRepo) { - $this->middleware('admin'); + $this->middleware(['admin', '2fa']); $this->customerMailRepo = $customerMailRepo; } diff --git a/app/Http/Controllers/CustomerMailController.php b/app/Http/Controllers/CustomerMailController.php index 352a629..eac562f 100755 --- a/app/Http/Controllers/CustomerMailController.php +++ b/app/Http/Controllers/CustomerMailController.php @@ -26,7 +26,7 @@ class CustomerMailController extends Controller public function __construct(CustomerMailRepository $customerMailRepo) { - $this->middleware('admin'); + $this->middleware(['admin', '2fa']); $this->customerMailRepo = $customerMailRepo; } @@ -129,7 +129,7 @@ class CustomerMailController extends Controller $value = new Collection(); $value->id = "add"; $value->customers = $customers; - $value->message = "Sehr #geehrte/r# #Anrede# #Vorname# #Nachname#,\n\nText ...."; + $value->message = "Sehr #geehrte:r# #Anrede# #Vorname# #Nachname#,\n\nText ...."; $data['title'] = "E-Mail-Nachricht an Auswahl"; $url = route('requests_send_customer_mail'); $ret = view("customer.mail.modal-mail", compact('data','value', 'url') )->render(); diff --git a/app/Http/Controllers/DraftController.php b/app/Http/Controllers/DraftController.php index dd31846..340e80d 100755 --- a/app/Http/Controllers/DraftController.php +++ b/app/Http/Controllers/DraftController.php @@ -11,8 +11,7 @@ class DraftController extends Controller { public function __construct() { - $this->middleware('admin'); - + $this->middleware(['admin', '2fa']); } public function index($step = false) diff --git a/app/Http/Controllers/IQ/ContentModalController.php b/app/Http/Controllers/IQ/ContentModalController.php index e10ff5a..57db3c9 100755 --- a/app/Http/Controllers/IQ/ContentModalController.php +++ b/app/Http/Controllers/IQ/ContentModalController.php @@ -21,7 +21,7 @@ class ContentModalController extends Controller */ public function __construct() { - // $this->middleware('auth'); + $this->middleware(['admin', '2fa']); } /** diff --git a/app/Http/Controllers/IQ/ContentTreeController.php b/app/Http/Controllers/IQ/ContentTreeController.php index d448503..cb8b862 100755 --- a/app/Http/Controllers/IQ/ContentTreeController.php +++ b/app/Http/Controllers/IQ/ContentTreeController.php @@ -26,7 +26,7 @@ class ContentTreeController extends Controller */ public function __construct(ContentSiteRepository $contentSiteRepo) { - $this->middleware('admin'); + $this->middleware(['admin', '2fa']); $this->contentSiteRepo = $contentSiteRepo; } diff --git a/app/Http/Controllers/IQ/Tools/ContentLinkController.php b/app/Http/Controllers/IQ/Tools/ContentLinkController.php index 77583f4..46944b6 100755 --- a/app/Http/Controllers/IQ/Tools/ContentLinkController.php +++ b/app/Http/Controllers/IQ/Tools/ContentLinkController.php @@ -19,7 +19,7 @@ class ContentLinkController extends Controller */ public function __construct() { - // $this->middleware('auth'); + $this->middleware(['sysadmin', '2fa']); } /** diff --git a/app/Http/Controllers/IQ/TravelGroupController.php b/app/Http/Controllers/IQ/TravelGroupController.php index 50b9658..9250265 100644 --- a/app/Http/Controllers/IQ/TravelGroupController.php +++ b/app/Http/Controllers/IQ/TravelGroupController.php @@ -16,7 +16,7 @@ class TravelGroupController extends Controller public function __construct(TravelRepository $tavelRepo) { - $this->middleware('admin'); + $this->middleware(['admin', '2fa']); $this->tavelRepo = $tavelRepo; } diff --git a/app/Http/Controllers/IQ/TravelItemController.php b/app/Http/Controllers/IQ/TravelItemController.php index 01c9ce6..6c7e4a9 100644 --- a/app/Http/Controllers/IQ/TravelItemController.php +++ b/app/Http/Controllers/IQ/TravelItemController.php @@ -16,7 +16,7 @@ class TravelItemController extends Controller public function __construct(TravelRepository $tavelRepo) { - $this->middleware('admin'); + $this->middleware(['admin', '2fa']); $this->tavelRepo = $tavelRepo; } diff --git a/app/Http/Controllers/IQ/TravelProgrammController.php b/app/Http/Controllers/IQ/TravelProgrammController.php index e3a1ea0..e462bf7 100644 --- a/app/Http/Controllers/IQ/TravelProgrammController.php +++ b/app/Http/Controllers/IQ/TravelProgrammController.php @@ -16,7 +16,7 @@ class TravelProgrammController extends Controller public function __construct(TravelRepository $travelRepo) { - $this->middleware('admin'); + $this->middleware(['admin', '2fa']); $this->travelRepo = $travelRepo; } diff --git a/app/Http/Controllers/LeadController.php b/app/Http/Controllers/LeadController.php index 5c8c87f..3c96a75 100755 --- a/app/Http/Controllers/LeadController.php +++ b/app/Http/Controllers/LeadController.php @@ -22,7 +22,7 @@ class LeadController extends Controller public function __construct(LeadRepository $leadRepo, CustomerRepository $custRepo) { - $this->middleware('admin'); + $this->middleware(['admin', '2fa']); $this->leadRepo = $leadRepo; $this->custRepo = $custRepo; @@ -238,6 +238,8 @@ class LeadController extends Controller if($lead->lead_mails->count()){ $lead_mail = $lead->lead_mails_sent_at->last(); + $badge = $lead_mail->is_answer ? 'badge-default' : 'badge-secondary'; + $badge = !$lead_mail->send ? $badge : 'badge-success'; return ' - '.$lead_mail->sent_at.' + ' + .($lead_mail->send ? '' : '').' ' + .$lead_mail->sent_at.' '; } return '-'; diff --git a/app/Http/Controllers/LeadMailController.php b/app/Http/Controllers/LeadMailController.php index 13d4214..a2e928e 100644 --- a/app/Http/Controllers/LeadMailController.php +++ b/app/Http/Controllers/LeadMailController.php @@ -28,7 +28,7 @@ class LeadMailController extends Controller public function __construct(LeadMailRepository $leadMailRepo) { - $this->middleware('admin'); + $this->middleware(['admin', '2fa']); $this->leadMailRepo = $leadMailRepo; } diff --git a/app/Http/Controllers/MailController.php b/app/Http/Controllers/MailController.php index 2c50382..99f1034 100644 --- a/app/Http/Controllers/MailController.php +++ b/app/Http/Controllers/MailController.php @@ -15,7 +15,7 @@ class MailController extends Controller public function __construct() { - $this->middleware('admin'); + $this->middleware(['admin', '2fa']); } public function leads() @@ -48,20 +48,6 @@ class MailController extends Controller ->addColumn('action_edit', function (LeadMail $lead_mail) { return ''; }) - ->addColumn('action_see', function (LeadMail $lead_mail) { - return ' - - '; - }) ->addColumn('lead_id', function (LeadMail $lead_mail) { return ''.$lead_mail->lead_id.''; }) @@ -69,10 +55,22 @@ class MailController extends Controller return $lead_mail->send ? '' : ''; }) ->addColumn('date', function (LeadMail $lead_mail) { - if($lead_mail->send){ - return ' '.$lead_mail->sent_at.''; - } - return ' '.$lead_mail->sent_at.''; + $badge = $lead_mail->is_answer ? 'badge-default' : 'badge-secondary'; + $badge = !$lead_mail->send ? $badge : 'badge-success'; + return ' + ' + .($lead_mail->send ? '' : '').' ' + .$lead_mail->sent_at.' + '; }) ->orderColumn('lead_id', 'lead_id $1') ->orderColumn('send', 'send $1') @@ -88,7 +86,7 @@ class MailController extends Controller $query->where('lead_id', 'LIKE', '%'.$keyword.'%'); } }) - ->rawColumns(['action_edit', 'send', 'date', 'lead_id', 'action_see']) + ->rawColumns(['action_edit', 'send', 'date', 'lead_id']) ->make(true); } @@ -100,20 +98,6 @@ class MailController extends Controller ->addColumn('action_edit', function (CustomerMail $customer_mail) { return ''; }) - ->addColumn('action_see', function (CustomerMail $customer_mail) { - return ' - - '; - }) ->addColumn('booking', function (CustomerMail $customer_mail) { $out = $customer_mail->booking->travel_country_id ? $customer_mail->booking->travel_country->name." | " : "- | "; $out .= $customer_mail->booking->travelagenda_id ? $customer_mail->booking->travel_agenda->name."" : "-"; @@ -126,10 +110,22 @@ class MailController extends Controller return $customer_mail->send ? '' : ''; }) ->addColumn('date', function (CustomerMail $customer_mail) { - if($customer_mail->send){ - return ' '.$customer_mail->sent_at.''; - } - return ' '.$customer_mail->sent_at.''; + $badge = $customer_mail->is_answer ? 'badge-default' : 'badge-secondary'; + $badge = !$customer_mail->send ? $badge : 'badge-success'; + return ' + ' + .($customer_mail->send ? '' : '').' ' + .$customer_mail->sent_at.' + '; }) ->orderColumn('booking_id', 'booking_id $1') ->orderColumn('send', 'send $1') @@ -157,21 +153,6 @@ class MailController extends Controller ->addColumn('action_edit', function (CustomerFewoMail $customer_fewo_mail) { return ''; }) - ->addColumn('action_see', function (CustomerFewoMail $customer_fewo_mail) { - return ' - - '; - }) - ->addColumn('booking', function (CustomerFewoMail $customer_fewo_mail) { $out = ($customer_fewo_mail->booking && $customer_fewo_mail->booking->fewo_lodging) ? $customer_fewo_mail->booking->fewo_lodging->name : "-"; return $out; @@ -183,10 +164,23 @@ class MailController extends Controller return $customer_fewo_mail->send ? '' : ''; }) ->addColumn('date', function (CustomerFewoMail $customer_fewo_mail) { - if($customer_fewo_mail->send){ - return ' '.$customer_fewo_mail->sent_at.''; - } - return ' '.$customer_fewo_mail->sent_at.''; + $badge = $customer_fewo_mail->is_answer ? 'badge-default' : 'badge-secondary'; + $badge = !$customer_fewo_mail->send ? $badge : 'badge-success'; + return ' + ' + .($customer_fewo_mail->send ? '' : '').' ' + .$customer_fewo_mail->sent_at.' + '; + }) ->orderColumn('booking_id', 'booking_id $1') ->orderColumn('send', 'send $1') @@ -202,7 +196,7 @@ class MailController extends Controller $query->where('booking_id', 'LIKE', '%'.$keyword.'%'); } }) - ->rawColumns(['action_edit', 'send', 'date', 'booking_id', 'action_see']) + ->rawColumns(['action_edit', 'send', 'date', 'booking_id']) ->make(true); } diff --git a/app/Http/Controllers/ModalController.php b/app/Http/Controllers/ModalController.php index 710bb37..94338fa 100644 --- a/app/Http/Controllers/ModalController.php +++ b/app/Http/Controllers/ModalController.php @@ -3,6 +3,7 @@ namespace App\Http\Controllers; use Request; +use App\Models\CMSContent; use App\Models\GeneralFile; use App\Models\IQContentSite; use App\Models\TravelCountry; @@ -19,7 +20,7 @@ class ModalController extends Controller public function __construct() { - $this->middleware('auth'); + $this->middleware(['admin', '2fa']); } public function load(){ @@ -104,6 +105,17 @@ class ModalController extends Controller $ret = view("admin.modal.iq_travel_program-item", compact('data', 'value'))->render(); } + if($data['action'] === 'modal-cms_booking_content_edit'){ + if($data['id'] === 'new'){ + $value = new CMSContent(); + }else{ + $value = CMSContent::find($data['id']); + } + $ret = view("admin.modal.cms_booking_content_edit", compact('data', 'value'))->render(); + } + + + } return response()->json(['response' => $data, 'html'=>$ret, 'status'=>$status]); } diff --git a/app/Http/Controllers/RequestController.php b/app/Http/Controllers/RequestController.php index 665c0e2..4986700 100755 --- a/app/Http/Controllers/RequestController.php +++ b/app/Http/Controllers/RequestController.php @@ -22,7 +22,7 @@ class RequestController extends Controller public function __construct() { - $this->middleware('admin'); + $this->middleware(['admin', '2fa']); } public function index($step = false) @@ -111,7 +111,6 @@ class RequestController extends Controller if(Request::get('travel_option_lead_status_id') != ""){ $query->whereHas('lead', function ($q) { $q->whereIn('status_id', Request::get('travel_option_lead_status_id')); - }); } if(Request::get('travel_option_paying_out') != ""){ @@ -426,6 +425,8 @@ class RequestController extends Controller ->addColumn('last_customer_email', function (Booking $booking) { if($booking->customer_mails->count()){ $customer_mail = $booking->customer_mails_sent_at->last(); + $badge = $customer_mail->is_answer ? 'badge-default' : 'badge-secondary'; + $badge = !$customer_mail->send ? $badge : 'badge-success'; return ' - '.$customer_mail->sent_at.' + ' + .($customer_mail->send ? '' : '').' ' + .$customer_mail->sent_at.' '; } return '-'; diff --git a/app/Http/Controllers/Settings/AirlineController.php b/app/Http/Controllers/Settings/AirlineController.php index a53fe1f..1c53b4f 100755 --- a/app/Http/Controllers/Settings/AirlineController.php +++ b/app/Http/Controllers/Settings/AirlineController.php @@ -13,8 +13,7 @@ class AirlineController extends Controller { public function __construct() { - $this->middleware('admin'); - + $this->middleware(['superadmin', '2fa']); } public function index($step = false) diff --git a/app/Http/Controllers/Settings/BookingStatusController.php b/app/Http/Controllers/Settings/BookingStatusController.php index ebd91f2..1eecaa5 100755 --- a/app/Http/Controllers/Settings/BookingStatusController.php +++ b/app/Http/Controllers/Settings/BookingStatusController.php @@ -11,7 +11,7 @@ class BookingStatusController extends Controller { public function __construct() { - $this->middleware('admin'); + $this->middleware(['superadmin', '2fa']); } public function index($step = false) diff --git a/app/Http/Controllers/Settings/CategoryController.php b/app/Http/Controllers/Settings/CategoryController.php index f89785e..a27a57d 100755 --- a/app/Http/Controllers/Settings/CategoryController.php +++ b/app/Http/Controllers/Settings/CategoryController.php @@ -12,7 +12,7 @@ class CategoryController extends Controller { public function __construct() { - $this->middleware('admin'); + $this->middleware(['superadmin', '2fa']); } public function index($step = false) diff --git a/app/Http/Controllers/Settings/EmailsController.php b/app/Http/Controllers/Settings/EmailsController.php index bd30731..a754d9b 100755 --- a/app/Http/Controllers/Settings/EmailsController.php +++ b/app/Http/Controllers/Settings/EmailsController.php @@ -21,11 +21,11 @@ class EmailsController extends Controller public function __construct() { - $this->identifier_booking_file = 'booking-email-file'; - $this->identifier_fewo_file = 'fewo-email-file'; - $this->identifier_lead_file = 'lead-email-file'; + $this->middleware(['superadmin', '2fa']); - $this->middleware('admin'); + $this->identifier_booking_file = 'booking-email-file'; + $this->identifier_fewo_file = 'fewo-email-file'; + $this->identifier_lead_file = 'lead-email-file'; } diff --git a/app/Http/Controllers/Settings/InsuranceController.php b/app/Http/Controllers/Settings/InsuranceController.php index 6fe168b..bd274a0 100755 --- a/app/Http/Controllers/Settings/InsuranceController.php +++ b/app/Http/Controllers/Settings/InsuranceController.php @@ -12,7 +12,7 @@ class InsuranceController extends Controller { public function __construct() { - $this->middleware('admin'); + $this->middleware(['superadmin', '2fa']); } public function index($step = false) diff --git a/app/Http/Controllers/Settings/KeywordController.php b/app/Http/Controllers/Settings/KeywordController.php index 831db94..77d7142 100755 --- a/app/Http/Controllers/Settings/KeywordController.php +++ b/app/Http/Controllers/Settings/KeywordController.php @@ -11,8 +11,7 @@ class KeywordController extends Controller { public function __construct() { - $this->middleware('admin'); - + $this->middleware(['superadmin', '2fa']); } public function index($step = false) diff --git a/app/Http/Controllers/Settings/ServiceProviderController.php b/app/Http/Controllers/Settings/ServiceProviderController.php index 986f762..a8214e3 100755 --- a/app/Http/Controllers/Settings/ServiceProviderController.php +++ b/app/Http/Controllers/Settings/ServiceProviderController.php @@ -13,7 +13,7 @@ class ServiceProviderController extends Controller { public function __construct() { - $this->middleware('admin'); + $this->middleware(['superadmin', '2fa']); } public function index($step = false) diff --git a/app/Http/Controllers/Settings/TravelAgendaController.php b/app/Http/Controllers/Settings/TravelAgendaController.php index da6a361..8794e04 100755 --- a/app/Http/Controllers/Settings/TravelAgendaController.php +++ b/app/Http/Controllers/Settings/TravelAgendaController.php @@ -12,8 +12,7 @@ class TravelAgendaController extends Controller { public function __construct() { - $this->middleware('admin'); - + $this->middleware(['superadmin', '2fa']); } public function index($step = false) diff --git a/app/Http/Controllers/Settings/TravelCompanyController.php b/app/Http/Controllers/Settings/TravelCompanyController.php index 11782fd..10d7621 100755 --- a/app/Http/Controllers/Settings/TravelCompanyController.php +++ b/app/Http/Controllers/Settings/TravelCompanyController.php @@ -13,7 +13,7 @@ class TravelCompanyController extends Controller { public function __construct() { - $this->middleware('admin'); + $this->middleware(['superadmin', '2fa']); } public function index($step = false) diff --git a/app/Http/Controllers/Settings/TravelCountryController.php b/app/Http/Controllers/Settings/TravelCountryController.php index 3355978..72ff519 100755 --- a/app/Http/Controllers/Settings/TravelCountryController.php +++ b/app/Http/Controllers/Settings/TravelCountryController.php @@ -25,8 +25,7 @@ class TravelCountryController extends Controller */ public function __construct() { - $this->middleware('admin'); - + $this->middleware(['superadmin', '2fa']); } public function index($step = false) diff --git a/app/Http/Controllers/Settings/TravelNationalityController.php b/app/Http/Controllers/Settings/TravelNationalityController.php index 7582456..cbccef4 100755 --- a/app/Http/Controllers/Settings/TravelNationalityController.php +++ b/app/Http/Controllers/Settings/TravelNationalityController.php @@ -12,8 +12,7 @@ class TravelNationalityController extends Controller { public function __construct() { - $this->middleware('admin'); - + $this->middleware(['superadmin', '2fa']); } public function index($step = false) @@ -24,7 +23,6 @@ class TravelNationalityController extends Controller return view('settings.travel_nationality.index', $data); } - public function update(){ $data = Request::all(); diff --git a/app/Http/Controllers/Settings/TravelPlaceController.php b/app/Http/Controllers/Settings/TravelPlaceController.php index aa7de21..09f613e 100644 --- a/app/Http/Controllers/Settings/TravelPlaceController.php +++ b/app/Http/Controllers/Settings/TravelPlaceController.php @@ -13,7 +13,7 @@ class TravelPlaceController extends Controller { public function __construct() { - $this->middleware('admin'); + $this->middleware(['superadmin', '2fa']); } public function index($step = false) @@ -24,12 +24,9 @@ class TravelPlaceController extends Controller return view('settings.place.index', $data); } - public function update(){ $data = Request::all(); - - $data['active'] = isset($data['active']) ? true : false; if($data['id'] === "new"){ diff --git a/app/Http/Controllers/SyS/Tools/ContentLinkController.php b/app/Http/Controllers/SyS/Tools/ContentLinkController.php index 9033fd7..ffa13a1 100755 --- a/app/Http/Controllers/SyS/Tools/ContentLinkController.php +++ b/app/Http/Controllers/SyS/Tools/ContentLinkController.php @@ -29,7 +29,7 @@ class ContentLinkController extends Controller */ public function __construct() { - // $this->middleware('auth'); + $this->middleware(['sysadmin', '2fa']); } public function filterHTML(){ diff --git a/app/Http/Controllers/TravelProgramController.php b/app/Http/Controllers/TravelProgramController.php index 729d4a4..6fd3111 100755 --- a/app/Http/Controllers/TravelProgramController.php +++ b/app/Http/Controllers/TravelProgramController.php @@ -15,7 +15,7 @@ class TravelProgramController extends Controller public function __construct(TravelProgramRepository $travelProgramRepo) { - $this->middleware('admin'); + $this->middleware(['admin', '2fa']); $this->travelProgramRepo = $travelProgramRepo; } diff --git a/app/Http/Controllers/TravelUserBookingFewoController.php b/app/Http/Controllers/TravelUserBookingFewoController.php index 9ec7fa8..44fd91a 100755 --- a/app/Http/Controllers/TravelUserBookingFewoController.php +++ b/app/Http/Controllers/TravelUserBookingFewoController.php @@ -22,13 +22,11 @@ use Request; class TravelUserBookingFewoController extends Controller { protected $userBookingFewoRepo; - // protected $identifier_fewo; public function __construct(TravelUserBookingFewoRepository $userBookingFewoRepo) { - $this->middleware('admin'); - $this->userBookingFewoRepo = $userBookingFewoRepo; - // $this->identifier_fewo = 'fewo-pdf-'; + $this->middleware(['admin', '2fa']); + $this->userBookingFewoRepo = $userBookingFewoRepo; } public function index($step = false) diff --git a/app/Http/Controllers/TravelUserController.php b/app/Http/Controllers/TravelUserController.php index 74005fd..385e342 100755 --- a/app/Http/Controllers/TravelUserController.php +++ b/app/Http/Controllers/TravelUserController.php @@ -11,8 +11,7 @@ class TravelUserController extends Controller { public function __construct() { - $this->middleware('admin'); - + $this->middleware(['admin', '2fa']); } public function index($step = false) diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php index 78807d1..511c00a 100755 --- a/app/Http/Kernel.php +++ b/app/Http/Kernel.php @@ -52,8 +52,9 @@ class Kernel extends HttpKernel * @var array */ protected $routeMiddleware = [ - 'auth' => \Illuminate\Auth\Middleware\Authenticate::class, + 'auth' => \App\Http\Middleware\Authenticate::class, 'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class, + '2fa' => \App\Http\Middleware\MiddleGoogle2FA::class, 'admin' => \App\Http\Middleware\Admin::class, 'superadmin' => \App\Http\Middleware\SuperAdmin::class, 'sysadmin' => \App\Http\Middleware\SysAdmin::class, diff --git a/app/Http/Middleware/AuthGoogle2FA.php b/app/Http/Middleware/AuthGoogle2FA.php new file mode 100644 index 0000000..37d9cb1 --- /dev/null +++ b/app/Http/Middleware/AuthGoogle2FA.php @@ -0,0 +1,24 @@ +init($request); + + if(!Auth::user()->isGoogle2Fa()){ + return $AuthGoogle2FA->makeActiveOneTimePasswordResponse(); + } + if ($AuthGoogle2FA->isAuthenticated()) { + return $next($request); + } + return $AuthGoogle2FA->makeRequestOneTimePasswordResponse(); + } +} + diff --git a/app/Http/Middleware/Authenticate.php b/app/Http/Middleware/Authenticate.php new file mode 100644 index 0000000..0ba367b --- /dev/null +++ b/app/Http/Middleware/Authenticate.php @@ -0,0 +1,99 @@ +auth = $auth; + } + + /** + * Handle an incoming request. + * + * @param \Illuminate\Http\Request $request + * @param \Closure $next + * @param string[] ...$guards + * @return mixed + * + * @throws \Illuminate\Auth\AuthenticationException + */ + public function handle($request, Closure $next, ...$guards) + { + $this->authenticate($request, $guards); + if(!$this->auth->user()->active){ + abort(403, 'Konto ist nicht aktiv'); + } + return $next($request); + } + + /** + * Determine if the user is logged in to any of the given guards. + * + * @param \Illuminate\Http\Request $request + * @param array $guards + * @return void + * + * @throws \Illuminate\Auth\AuthenticationException + */ + protected function authenticate($request, array $guards) + { + if (empty($guards)) { + $guards = [null]; + } + + foreach ($guards as $guard) { + if ($this->auth->guard($guard)->check()) { + return $this->auth->shouldUse($guard); + } + } + + $this->unauthenticated($request, $guards); + } + + /** + * Handle an unauthenticated user. + * + * @param \Illuminate\Http\Request $request + * @param array $guards + * @return void + * + * @throws \Illuminate\Auth\AuthenticationException + */ + protected function unauthenticated($request, array $guards) + { + throw new AuthenticationException( + 'Unauthenticated.', $guards, $this->redirectTo($request) + ); + } + + /** + * Get the path the user should be redirected to when they are not authenticated. + * + * @param \Illuminate\Http\Request $request + * @return string|null + */ + protected function redirectTo($request) + { + // + } +} diff --git a/app/Http/Middleware/Google2FA.php b/app/Http/Middleware/Google2FA.php new file mode 100644 index 0000000..1bf49af --- /dev/null +++ b/app/Http/Middleware/Google2FA.php @@ -0,0 +1,24 @@ +init($request); + + if(!Auth::user()->isGoogle2Fa()){ + return $AuthGoogle2FA->makeActiveOneTimePasswordResponse(); + } + if ($AuthGoogle2FA->isAuthenticated()) { + return $next($request); + } + return $AuthGoogle2FA->makeRequestOneTimePasswordResponse(); + } +} + diff --git a/app/Http/Middleware/Google2FAAuth.php b/app/Http/Middleware/Google2FAAuth.php new file mode 100644 index 0000000..15b67db --- /dev/null +++ b/app/Http/Middleware/Google2FAAuth.php @@ -0,0 +1,25 @@ +boot($request); + dd(Auth::user()->isGoogle2Fa()); + if(Auth::user()->isGoogle2Fa()){ + + } + if ($authenticator->isAuthenticated()) { + return $next($request); + } + + return $authenticator->makeRequestOneTimePasswordResponse(); + } +} + diff --git a/app/Http/Middleware/MiddleGoogle2FA.php b/app/Http/Middleware/MiddleGoogle2FA.php new file mode 100644 index 0000000..42c3334 --- /dev/null +++ b/app/Http/Middleware/MiddleGoogle2FA.php @@ -0,0 +1,24 @@ +init($request); + + if(!Auth::user()->isGoogle2Fa()){ + \App\Services\MyGoogle2FA::logout(); + return $AuthGoogle2FA->makeActiveOneTimePasswordResponse(); + } + if ($AuthGoogle2FA->isAuthenticated()) { + return $next($request); + } + return $AuthGoogle2FA->makeRequestOneTimePasswordResponse(); + } +} \ No newline at end of file diff --git a/app/Models/Airline.php b/app/Models/Airline.php index 48ce631..b83cf55 100644 --- a/app/Models/Airline.php +++ b/app/Models/Airline.php @@ -31,6 +31,12 @@ use Illuminate\Database\Eloquent\Model; * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Airline whereNameFull($value) * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Airline whereUpdatedAt($value) * @mixin \Eloquent + * @property string|null $flight_info + * @property string|null $check_in + * @property string|null $baggage + * @method static \Illuminate\Database\Eloquent\Builder|Airline whereBaggage($value) + * @method static \Illuminate\Database\Eloquent\Builder|Airline whereCheckIn($value) + * @method static \Illuminate\Database\Eloquent\Builder|Airline whereFlightInfo($value) */ class Airline extends Model { diff --git a/app/Models/Booking.php b/app/Models/Booking.php index 0096239..7ae553e 100644 --- a/app/Models/Booking.php +++ b/app/Models/Booking.php @@ -183,6 +183,11 @@ use Illuminate\Database\Eloquent\Collection; * @property-read \App\Models\TravelNationality|null $travel_nationality * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Booking whereComfort($value) * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Booking whereNationalityId($value) + * @property bool|null $participant_pass + * @property array|null $airline_ids + * @property-read \App\Models\BookingStorno|null $booking_strono + * @method static \Illuminate\Database\Eloquent\Builder|Booking whereAirlineIds($value) + * @method static \Illuminate\Database\Eloquent\Builder|Booking whereParticipantPass($value) */ class Booking extends Model { diff --git a/app/Models/Branch.php b/app/Models/Branch.php index d1f0406..77146d1 100644 --- a/app/Models/Branch.php +++ b/app/Models/Branch.php @@ -11,14 +11,20 @@ use Illuminate\Database\Eloquent\Model; /** * Class Branch - * + * * @property int $id * @property string $name - * * @property Collection|Booking[] $bookings * @property Collection|SfGuardUser[] $sf_guard_users - * * @package App\Models + * @property-read int|null $bookings_count + * @property-read int|null $sf_guard_users_count + * @method static \Illuminate\Database\Eloquent\Builder|Branch newModelQuery() + * @method static \Illuminate\Database\Eloquent\Builder|Branch newQuery() + * @method static \Illuminate\Database\Eloquent\Builder|Branch query() + * @method static \Illuminate\Database\Eloquent\Builder|Branch whereId($value) + * @method static \Illuminate\Database\Eloquent\Builder|Branch whereName($value) + * @mixin \Eloquent */ class Branch extends Model { diff --git a/app/Models/CMSContent.php b/app/Models/CMSContent.php index 1907ec1..64eaddf 100644 --- a/app/Models/CMSContent.php +++ b/app/Models/CMSContent.php @@ -38,6 +38,7 @@ use Illuminate\Database\Eloquent\Model; * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\CMSContent whereObject($value) * @property int|null $pos * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\CMSContent wherePos($value) + * @method static \Illuminate\Database\Eloquent\Builder|CMSContent withUniqueSlugConstraints(\Illuminate\Database\Eloquent\Model $model, string $attribute, array $config, string $slug) */ class CMSContent extends Model { @@ -82,6 +83,16 @@ class CMSContent extends Model ]; } + public function setNameAttribute($value){ + $this->attributes['name'] = $value == '' ? '#empty#' : $value; + + } + + public function getNameWithEmpty(){ + if(!$this->attributes['name']){ return ""; } + return $this->attributes['name'] === '#empty#' ? '' : $this->attributes['name']; + } + public static function getFieldsOptions($setKey = false){ $options = self::$fields; $ret = ""; @@ -229,6 +240,11 @@ class CMSContent extends Model $this->object = $obj; } + public static function findObjectsBy($key, $value){ + $find = '"'.$key.'":"'.$value.'"'; + return CMSContent::where('object', 'LIKE', '%'.$find.'%')->get(); + } + public static function getContentBySlug($slug){ $CMSContent = CMSContent::whereSlug(trim($slug))->first(); if($CMSContent){ diff --git a/app/Models/CMSInfo.php b/app/Models/CMSInfo.php index 14914ae..4dc72ec 100644 --- a/app/Models/CMSInfo.php +++ b/app/Models/CMSInfo.php @@ -39,6 +39,7 @@ use Illuminate\Database\Eloquent\Model; * @property int $bool * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\CMSInfo whereBool($value) * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\CMSInfo whereType($value) + * @method static \Illuminate\Database\Eloquent\Builder|CMSInfo withUniqueSlugConstraints(\Illuminate\Database\Eloquent\Model $model, string $attribute, array $config, string $slug) */ class CMSInfo extends Model { diff --git a/app/Models/IQContentCategory.php b/app/Models/IQContentCategory.php index 7a51e32..b482038 100644 --- a/app/Models/IQContentCategory.php +++ b/app/Models/IQContentCategory.php @@ -38,6 +38,7 @@ use Illuminate\Database\Eloquent\Model; * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\IQContentCategory whereSlug($value) * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\IQContentCategory whereUpdatedAt($value) * @mixin \Eloquent + * @method static \Illuminate\Database\Eloquent\Builder|IQContentCategory withUniqueSlugConstraints(\Illuminate\Database\Eloquent\Model $model, string $attribute, array $config, string $slug) */ class IQContentCategory extends Model { diff --git a/app/Models/IQContentTree.php b/app/Models/IQContentTree.php index 43cd5d6..19f1ec2 100644 --- a/app/Models/IQContentTree.php +++ b/app/Models/IQContentTree.php @@ -48,6 +48,7 @@ use Illuminate\Support\Str; * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\IQContentTree wherePageId($value) * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\IQContentTree whereRootId($value) * @property-read int|null $iq_content_tree_nodes_count + * @method static \Illuminate\Database\Eloquent\Builder|IQContentTree withUniqueSlugConstraints(\Illuminate\Database\Eloquent\Model $model, string $attribute, array $config, string $slug) */ class IQContentTree extends Model { diff --git a/app/Models/IQContentTreeNode.php b/app/Models/IQContentTreeNode.php index 361f216..c760839 100644 --- a/app/Models/IQContentTreeNode.php +++ b/app/Models/IQContentTreeNode.php @@ -63,6 +63,7 @@ use Illuminate\Support\Str; * @property-read int|null $iq_content_faq_count * @property-read \Illuminate\Database\Eloquent\Collection|\App\Models\IQContentFaq[] $iq_content_faqs * @property-read int|null $iq_content_faqs_count + * @method static \Illuminate\Database\Eloquent\Builder|IQContentTreeNode withUniqueSlugConstraints(\Illuminate\Database\Eloquent\Model $model, string $attribute, array $config, string $slug) */ class IQContentTreeNode extends Model { diff --git a/app/Models/IQTravelGroup.php b/app/Models/IQTravelGroup.php index 634bfdd..d05deb4 100644 --- a/app/Models/IQTravelGroup.php +++ b/app/Models/IQTravelGroup.php @@ -13,7 +13,7 @@ use Illuminate\Database\Eloquent\Collection; /** * Class IQTravelGroup - * + * * @property int $id * @property string $name * @property string $description @@ -27,10 +27,26 @@ use Illuminate\Database\Eloquent\Collection; * @property bool $active * @property Carbon $created_at * @property Carbon $updated_at - * * @property Collection|IQTravelGroupItem[] $i_q_travel_group_items - * * @package App\Models + * @property-read int|null $i_q_travel_group_items_count + * @method static \Illuminate\Database\Eloquent\Builder|IQTravelGroup newModelQuery() + * @method static \Illuminate\Database\Eloquent\Builder|IQTravelGroup newQuery() + * @method static \Illuminate\Database\Eloquent\Builder|IQTravelGroup query() + * @method static \Illuminate\Database\Eloquent\Builder|IQTravelGroup whereActive($value) + * @method static \Illuminate\Database\Eloquent\Builder|IQTravelGroup whereCreatedAt($value) + * @method static \Illuminate\Database\Eloquent\Builder|IQTravelGroup whereDaysDuration($value) + * @method static \Illuminate\Database\Eloquent\Builder|IQTravelGroup whereDaysStart($value) + * @method static \Illuminate\Database\Eloquent\Builder|IQTravelGroup whereDescription($value) + * @method static \Illuminate\Database\Eloquent\Builder|IQTravelGroup whereHighlights($value) + * @method static \Illuminate\Database\Eloquent\Builder|IQTravelGroup whereId($value) + * @method static \Illuminate\Database\Eloquent\Builder|IQTravelGroup whereMinPersons($value) + * @method static \Illuminate\Database\Eloquent\Builder|IQTravelGroup whereName($value) + * @method static \Illuminate\Database\Eloquent\Builder|IQTravelGroup wherePos($value) + * @method static \Illuminate\Database\Eloquent\Builder|IQTravelGroup wherePriceAdult($value) + * @method static \Illuminate\Database\Eloquent\Builder|IQTravelGroup wherePriceChildren($value) + * @method static \Illuminate\Database\Eloquent\Builder|IQTravelGroup whereUpdatedAt($value) + * @mixin \Eloquent */ class IQTravelGroup extends Model { diff --git a/app/Models/IQTravelGroupItem.php b/app/Models/IQTravelGroupItem.php index d5cc52d..a1d1ad9 100644 --- a/app/Models/IQTravelGroupItem.php +++ b/app/Models/IQTravelGroupItem.php @@ -11,18 +11,26 @@ use Illuminate\Database\Eloquent\Model; /** * Class IQTravelGroupItem - * + * * @property int $id * @property int $i_q_travel_group_id * @property int $i_q_travel_item_id * @property int $pos * @property Carbon $created_at * @property Carbon $updated_at - * * @property IQTravelGroup $i_q_travel_group * @property IQTravelItem $i_q_travel_item - * * @package App\Models + * @method static \Illuminate\Database\Eloquent\Builder|IQTravelGroupItem newModelQuery() + * @method static \Illuminate\Database\Eloquent\Builder|IQTravelGroupItem newQuery() + * @method static \Illuminate\Database\Eloquent\Builder|IQTravelGroupItem query() + * @method static \Illuminate\Database\Eloquent\Builder|IQTravelGroupItem whereCreatedAt($value) + * @method static \Illuminate\Database\Eloquent\Builder|IQTravelGroupItem whereIQTravelGroupId($value) + * @method static \Illuminate\Database\Eloquent\Builder|IQTravelGroupItem whereIQTravelItemId($value) + * @method static \Illuminate\Database\Eloquent\Builder|IQTravelGroupItem whereId($value) + * @method static \Illuminate\Database\Eloquent\Builder|IQTravelGroupItem wherePos($value) + * @method static \Illuminate\Database\Eloquent\Builder|IQTravelGroupItem whereUpdatedAt($value) + * @mixin \Eloquent */ class IQTravelGroupItem extends Model { diff --git a/app/Models/IQTravelItem.php b/app/Models/IQTravelItem.php index 45841b5..fcaf21f 100644 --- a/app/Models/IQTravelItem.php +++ b/app/Models/IQTravelItem.php @@ -13,7 +13,7 @@ use Illuminate\Database\Eloquent\Collection; /** * Class IQTravelItem - * + * * @property int $id * @property string $name * @property string $description @@ -29,12 +29,32 @@ use Illuminate\Database\Eloquent\Collection; * @property bool $active * @property Carbon $created_at * @property Carbon $updated_at - * * @property TravelCountry $travel_country * @property Collection|IQTravelGroupItem[] $i_q_travel_group_items * @property Collection|IQTravelItemPlace[] $i_q_travel_item_places - * * @package App\Models + * @property-read \App\Models\DraftType|null $draft_type + * @property-read int|null $i_q_travel_group_items_count + * @property-read int|null $i_q_travel_item_places_count + * @method static \Illuminate\Database\Eloquent\Builder|IQTravelItem newModelQuery() + * @method static \Illuminate\Database\Eloquent\Builder|IQTravelItem newQuery() + * @method static \Illuminate\Database\Eloquent\Builder|IQTravelItem query() + * @method static \Illuminate\Database\Eloquent\Builder|IQTravelItem whereActive($value) + * @method static \Illuminate\Database\Eloquent\Builder|IQTravelItem whereCreatedAt($value) + * @method static \Illuminate\Database\Eloquent\Builder|IQTravelItem whereDaysDuration($value) + * @method static \Illuminate\Database\Eloquent\Builder|IQTravelItem whereDaysStart($value) + * @method static \Illuminate\Database\Eloquent\Builder|IQTravelItem whereDescription($value) + * @method static \Illuminate\Database\Eloquent\Builder|IQTravelItem whereDraftTypeId($value) + * @method static \Illuminate\Database\Eloquent\Builder|IQTravelItem whereHighlights($value) + * @method static \Illuminate\Database\Eloquent\Builder|IQTravelItem whereId($value) + * @method static \Illuminate\Database\Eloquent\Builder|IQTravelItem whereMinPersons($value) + * @method static \Illuminate\Database\Eloquent\Builder|IQTravelItem whereName($value) + * @method static \Illuminate\Database\Eloquent\Builder|IQTravelItem wherePos($value) + * @method static \Illuminate\Database\Eloquent\Builder|IQTravelItem wherePriceAdult($value) + * @method static \Illuminate\Database\Eloquent\Builder|IQTravelItem wherePriceChildren($value) + * @method static \Illuminate\Database\Eloquent\Builder|IQTravelItem whereTravelCountryId($value) + * @method static \Illuminate\Database\Eloquent\Builder|IQTravelItem whereUpdatedAt($value) + * @mixin \Eloquent */ class IQTravelItem extends Model { diff --git a/app/Models/IQTravelItemPlace.php b/app/Models/IQTravelItemPlace.php index 79b55f5..8e54001 100644 --- a/app/Models/IQTravelItemPlace.php +++ b/app/Models/IQTravelItemPlace.php @@ -11,18 +11,26 @@ use Illuminate\Database\Eloquent\Model; /** * Class IQTravelItemPlace - * + * * @property int $id * @property int $i_q_travel_item_id * @property int $travel_place_id * @property int $pos * @property Carbon $created_at * @property Carbon $updated_at - * * @property IQTravelItem $i_q_travel_item * @property TravelPlace $travel_place - * * @package App\Models + * @method static \Illuminate\Database\Eloquent\Builder|IQTravelItemPlace newModelQuery() + * @method static \Illuminate\Database\Eloquent\Builder|IQTravelItemPlace newQuery() + * @method static \Illuminate\Database\Eloquent\Builder|IQTravelItemPlace query() + * @method static \Illuminate\Database\Eloquent\Builder|IQTravelItemPlace whereCreatedAt($value) + * @method static \Illuminate\Database\Eloquent\Builder|IQTravelItemPlace whereIQTravelItemId($value) + * @method static \Illuminate\Database\Eloquent\Builder|IQTravelItemPlace whereId($value) + * @method static \Illuminate\Database\Eloquent\Builder|IQTravelItemPlace wherePos($value) + * @method static \Illuminate\Database\Eloquent\Builder|IQTravelItemPlace whereTravelPlaceId($value) + * @method static \Illuminate\Database\Eloquent\Builder|IQTravelItemPlace whereUpdatedAt($value) + * @mixin \Eloquent */ class IQTravelItemPlace extends Model { diff --git a/app/Models/IQTravelProgram.php b/app/Models/IQTravelProgram.php index 97561ea..27cec3b 100644 --- a/app/Models/IQTravelProgram.php +++ b/app/Models/IQTravelProgram.php @@ -13,7 +13,7 @@ use Illuminate\Database\Eloquent\Collection; /** * Class IQTravelProgram - * + * * @property int $id * @property string $name * @property string $code @@ -31,11 +31,33 @@ use Illuminate\Database\Eloquent\Collection; * @property bool $active * @property Carbon $created_at * @property Carbon $updated_at - * * @property TravelCountry $travel_country * @property Collection|IQTravelProgramItem[] $i_q_travel_program_items - * * @package App\Models + * @property int|null $typ + * @property-read int|null $i_q_travel_program_items_count + * @method static \Illuminate\Database\Eloquent\Builder|IQTravelProgram newModelQuery() + * @method static \Illuminate\Database\Eloquent\Builder|IQTravelProgram newQuery() + * @method static \Illuminate\Database\Eloquent\Builder|IQTravelProgram query() + * @method static \Illuminate\Database\Eloquent\Builder|IQTravelProgram whereActive($value) + * @method static \Illuminate\Database\Eloquent\Builder|IQTravelProgram whereCode($value) + * @method static \Illuminate\Database\Eloquent\Builder|IQTravelProgram whereCreatedAt($value) + * @method static \Illuminate\Database\Eloquent\Builder|IQTravelProgram whereDaysDuration($value) + * @method static \Illuminate\Database\Eloquent\Builder|IQTravelProgram whereDepositPro($value) + * @method static \Illuminate\Database\Eloquent\Builder|IQTravelProgram whereDescription($value) + * @method static \Illuminate\Database\Eloquent\Builder|IQTravelProgram whereDiscount($value) + * @method static \Illuminate\Database\Eloquent\Builder|IQTravelProgram whereHighlights($value) + * @method static \Illuminate\Database\Eloquent\Builder|IQTravelProgram whereId($value) + * @method static \Illuminate\Database\Eloquent\Builder|IQTravelProgram whereName($value) + * @method static \Illuminate\Database\Eloquent\Builder|IQTravelProgram whereNotIncluded($value) + * @method static \Illuminate\Database\Eloquent\Builder|IQTravelProgram wherePriceAdultTotal($value) + * @method static \Illuminate\Database\Eloquent\Builder|IQTravelProgram wherePriceChildrenTotal($value) + * @method static \Illuminate\Database\Eloquent\Builder|IQTravelProgram whereTravelCountryId($value) + * @method static \Illuminate\Database\Eloquent\Builder|IQTravelProgram whereTravelInsurance($value) + * @method static \Illuminate\Database\Eloquent\Builder|IQTravelProgram whereTyp($value) + * @method static \Illuminate\Database\Eloquent\Builder|IQTravelProgram whereUpdatedAt($value) + * @method static \Illuminate\Database\Eloquent\Builder|IQTravelProgram whereWeekdays($value) + * @mixin \Eloquent */ class IQTravelProgram extends Model { diff --git a/app/Models/IQTravelProgramItem.php b/app/Models/IQTravelProgramItem.php index 49471a4..469ce85 100644 --- a/app/Models/IQTravelProgramItem.php +++ b/app/Models/IQTravelProgramItem.php @@ -11,7 +11,7 @@ use Illuminate\Database\Eloquent\Model; /** * Class IQTravelProgramItem - * + * * @property int $id * @property int $i_q_travel_program_id * @property int $i_q_travel_item_id @@ -21,12 +21,23 @@ use Illuminate\Database\Eloquent\Model; * @property bool $active * @property Carbon $created_at * @property Carbon $updated_at - * * @property IQTravelGroup $i_q_travel_group * @property IQTravelItem $i_q_travel_item * @property IQTravelProgram $i_q_travel_program - * * @package App\Models + * @method static \Illuminate\Database\Eloquent\Builder|IQTravelProgramItem newModelQuery() + * @method static \Illuminate\Database\Eloquent\Builder|IQTravelProgramItem newQuery() + * @method static \Illuminate\Database\Eloquent\Builder|IQTravelProgramItem query() + * @method static \Illuminate\Database\Eloquent\Builder|IQTravelProgramItem whereActive($value) + * @method static \Illuminate\Database\Eloquent\Builder|IQTravelProgramItem whereCreatedAt($value) + * @method static \Illuminate\Database\Eloquent\Builder|IQTravelProgramItem whereIQTravelGroupId($value) + * @method static \Illuminate\Database\Eloquent\Builder|IQTravelProgramItem whereIQTravelItemId($value) + * @method static \Illuminate\Database\Eloquent\Builder|IQTravelProgramItem whereIQTravelProgramId($value) + * @method static \Illuminate\Database\Eloquent\Builder|IQTravelProgramItem whereId($value) + * @method static \Illuminate\Database\Eloquent\Builder|IQTravelProgramItem wherePos($value) + * @method static \Illuminate\Database\Eloquent\Builder|IQTravelProgramItem whereTyp($value) + * @method static \Illuminate\Database\Eloquent\Builder|IQTravelProgramItem whereUpdatedAt($value) + * @mixin \Eloquent */ class IQTravelProgramItem extends Model { diff --git a/app/Models/Lead.php b/app/Models/Lead.php index 2296cff..b1ca760 100644 --- a/app/Models/Lead.php +++ b/app/Models/Lead.php @@ -95,6 +95,15 @@ use Illuminate\Database\Eloquent\Collection; * @property-read \App\Models\Sym\TravelCountry|null $travel_country_crm * @property bool|null $is_rebook * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Lead whereIsRebook($value) + * @property-read Collection|\App\Models\LeadFile[] $lead_files + * @property-read int|null $lead_files_count + * @property-read \App\Models\LeadMail|null $lead_mail_last + * @property-read Collection|\App\Models\LeadMail[] $lead_mails + * @property-read int|null $lead_mails_count + * @property-read Collection|\App\Models\LeadMail[] $lead_mails_sent_at + * @property-read int|null $lead_mails_sent_at_count + * @property-read Collection|\App\Models\LeadNotice[] $lead_notices + * @property-read int|null $lead_notices_count */ class Lead extends Model { diff --git a/app/Models/LeadFile.php b/app/Models/LeadFile.php index 79c377d..d6c1203 100644 --- a/app/Models/LeadFile.php +++ b/app/Models/LeadFile.php @@ -11,7 +11,7 @@ use Illuminate\Database\Eloquent\Model; /** * Class LeadFile - * + * * @property int $id * @property int $lead_id * @property int $lead_mail_id @@ -24,11 +24,25 @@ use Illuminate\Database\Eloquent\Model; * @property int $size * @property Carbon $created_at * @property Carbon $updated_at - * * @property Lead $lead * @property LeadMail $lead_mail - * * @package App\Models + * @method static \Illuminate\Database\Eloquent\Builder|LeadFile newModelQuery() + * @method static \Illuminate\Database\Eloquent\Builder|LeadFile newQuery() + * @method static \Illuminate\Database\Eloquent\Builder|LeadFile query() + * @method static \Illuminate\Database\Eloquent\Builder|LeadFile whereCreatedAt($value) + * @method static \Illuminate\Database\Eloquent\Builder|LeadFile whereDir($value) + * @method static \Illuminate\Database\Eloquent\Builder|LeadFile whereExt($value) + * @method static \Illuminate\Database\Eloquent\Builder|LeadFile whereFilename($value) + * @method static \Illuminate\Database\Eloquent\Builder|LeadFile whereId($value) + * @method static \Illuminate\Database\Eloquent\Builder|LeadFile whereIdentifier($value) + * @method static \Illuminate\Database\Eloquent\Builder|LeadFile whereLeadId($value) + * @method static \Illuminate\Database\Eloquent\Builder|LeadFile whereLeadMailId($value) + * @method static \Illuminate\Database\Eloquent\Builder|LeadFile whereMine($value) + * @method static \Illuminate\Database\Eloquent\Builder|LeadFile whereOriginalName($value) + * @method static \Illuminate\Database\Eloquent\Builder|LeadFile whereSize($value) + * @method static \Illuminate\Database\Eloquent\Builder|LeadFile whereUpdatedAt($value) + * @mixin \Eloquent */ class LeadFile extends Model { diff --git a/app/Models/LeadMail.php b/app/Models/LeadMail.php index 55b59bb..ac40ed8 100644 --- a/app/Models/LeadMail.php +++ b/app/Models/LeadMail.php @@ -12,7 +12,7 @@ use Illuminate\Database\Eloquent\Model; /** * Class LeadMail - * + * * @property int $id * @property int $lead_id * @property int $customer_id @@ -37,13 +37,41 @@ use Illuminate\Database\Eloquent\Model; * @property Carbon $delivered_at * @property Carbon $created_at * @property Carbon $updated_at - * * @property Customer $customer * @property Lead $lead * @property CustomerMail $customer_mail * @property Collection|LeadFile[] $lead_files - * * @package App\Models + * @property-read int|null $lead_files_count + * @property-read LeadMail|null $lead_mail + * @method static \Illuminate\Database\Eloquent\Builder|LeadMail newModelQuery() + * @method static \Illuminate\Database\Eloquent\Builder|LeadMail newQuery() + * @method static \Illuminate\Database\Eloquent\Builder|LeadMail query() + * @method static \Illuminate\Database\Eloquent\Builder|LeadMail whereBcc($value) + * @method static \Illuminate\Database\Eloquent\Builder|LeadMail whereCc($value) + * @method static \Illuminate\Database\Eloquent\Builder|LeadMail whereCreatedAt($value) + * @method static \Illuminate\Database\Eloquent\Builder|LeadMail whereCustomerId($value) + * @method static \Illuminate\Database\Eloquent\Builder|LeadMail whereDeliveredAt($value) + * @method static \Illuminate\Database\Eloquent\Builder|LeadMail whereDir($value) + * @method static \Illuminate\Database\Eloquent\Builder|LeadMail whereDraft($value) + * @method static \Illuminate\Database\Eloquent\Builder|LeadMail whereEmail($value) + * @method static \Illuminate\Database\Eloquent\Builder|LeadMail whereError($value) + * @method static \Illuminate\Database\Eloquent\Builder|LeadMail whereFail($value) + * @method static \Illuminate\Database\Eloquent\Builder|LeadMail whereForward($value) + * @method static \Illuminate\Database\Eloquent\Builder|LeadMail whereId($value) + * @method static \Illuminate\Database\Eloquent\Builder|LeadMail whereImportant($value) + * @method static \Illuminate\Database\Eloquent\Builder|LeadMail whereIsAnswer($value) + * @method static \Illuminate\Database\Eloquent\Builder|LeadMail whereLeadId($value) + * @method static \Illuminate\Database\Eloquent\Builder|LeadMail whereMessage($value) + * @method static \Illuminate\Database\Eloquent\Builder|LeadMail whereRecipient($value) + * @method static \Illuminate\Database\Eloquent\Builder|LeadMail whereReplyId($value) + * @method static \Illuminate\Database\Eloquent\Builder|LeadMail whereScheduledAt($value) + * @method static \Illuminate\Database\Eloquent\Builder|LeadMail whereSend($value) + * @method static \Illuminate\Database\Eloquent\Builder|LeadMail whereSentAt($value) + * @method static \Illuminate\Database\Eloquent\Builder|LeadMail whereSubdir($value) + * @method static \Illuminate\Database\Eloquent\Builder|LeadMail whereSubject($value) + * @method static \Illuminate\Database\Eloquent\Builder|LeadMail whereUpdatedAt($value) + * @mixin \Eloquent */ class LeadMail extends Model { diff --git a/app/Models/LeadNotice.php b/app/Models/LeadNotice.php index c1f15dc..3ecdad3 100644 --- a/app/Models/LeadNotice.php +++ b/app/Models/LeadNotice.php @@ -13,7 +13,7 @@ use App\User; /** * Class LeadNotice - * + * * @property int $id * @property int $lead_id * @property int $from_user_id @@ -24,11 +24,25 @@ use App\User; * @property Carbon $edit_at * @property Carbon $created_at * @property Carbon $updated_at - * * @property User $user * @property Lead $lead - * * @package App\Models + * @property-read User $from_user + * @property-read User|null $to_user + * @method static \Illuminate\Database\Eloquent\Builder|LeadNotice newModelQuery() + * @method static \Illuminate\Database\Eloquent\Builder|LeadNotice newQuery() + * @method static \Illuminate\Database\Eloquent\Builder|LeadNotice query() + * @method static \Illuminate\Database\Eloquent\Builder|LeadNotice whereCreatedAt($value) + * @method static \Illuminate\Database\Eloquent\Builder|LeadNotice whereEditAt($value) + * @method static \Illuminate\Database\Eloquent\Builder|LeadNotice whereFromUserId($value) + * @method static \Illuminate\Database\Eloquent\Builder|LeadNotice whereId($value) + * @method static \Illuminate\Database\Eloquent\Builder|LeadNotice whereImportant($value) + * @method static \Illuminate\Database\Eloquent\Builder|LeadNotice whereLeadId($value) + * @method static \Illuminate\Database\Eloquent\Builder|LeadNotice whereMessage($value) + * @method static \Illuminate\Database\Eloquent\Builder|LeadNotice whereShow($value) + * @method static \Illuminate\Database\Eloquent\Builder|LeadNotice whereToUserId($value) + * @method static \Illuminate\Database\Eloquent\Builder|LeadNotice whereUpdatedAt($value) + * @mixin \Eloquent */ class LeadNotice extends Model { diff --git a/app/Models/LeadParticipant.php b/app/Models/LeadParticipant.php index ac7b432..add930c 100644 --- a/app/Models/LeadParticipant.php +++ b/app/Models/LeadParticipant.php @@ -31,6 +31,11 @@ use Illuminate\Database\Eloquent\Model; * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\LeadParticipant whereParticipantName($value) * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\LeadParticipant whereParticipantSalutationId($value) * @mixin \Eloquent + * @property int|null $participant_child + * @property int|null $nationality_id + * @property-read \App\Models\TravelNationality|null $travel_nationality + * @method static \Illuminate\Database\Eloquent\Builder|LeadParticipant whereNationalityId($value) + * @method static \Illuminate\Database\Eloquent\Builder|LeadParticipant whereParticipantChild($value) */ class LeadParticipant extends Model { diff --git a/app/Models/Participant.php b/app/Models/Participant.php index a62c861..f6fcb88 100644 --- a/app/Models/Participant.php +++ b/app/Models/Participant.php @@ -36,6 +36,10 @@ use Illuminate\Database\Eloquent\Model; * @property int|null $nationality_id * @property-read \App\Models\TravelNationality|null $travel_nationality * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Participant whereNationalityId($value) + * @property bool|null $participant_pass + * @property bool|null $participant_storno + * @method static \Illuminate\Database\Eloquent\Builder|Participant whereParticipantPass($value) + * @method static \Illuminate\Database\Eloquent\Builder|Participant whereParticipantStorno($value) */ class Participant extends Model { @@ -48,7 +52,9 @@ class Participant extends Model 'booking_id' => 'int', 'participant_salutation_id' => 'int', 'participant_child' => 'bool', - 'participant_pass' => 'bool' + 'participant_pass' => 'bool', + 'participant_storno' => 'bool' + ]; protected $dates = [ @@ -63,7 +69,8 @@ class Participant extends Model 'participant_salutation_id', 'participant_child', 'nationality_id', - 'participant_pass' + 'participant_pass', + 'participant_storno' ]; public function booking() diff --git a/app/Models/SfGuardUser.php b/app/Models/SfGuardUser.php index d3dbf4e..145747e 100755 --- a/app/Models/SfGuardUser.php +++ b/app/Models/SfGuardUser.php @@ -54,6 +54,7 @@ use Illuminate\Database\Eloquent\Model; * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\SfGuardUser newQuery() * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\SfGuardUser query() * @property-read \App\User|null $user + * @property-read mixed $fullname */ class SfGuardUser extends Model { diff --git a/app/Models/Sym/CmsContent.php b/app/Models/Sym/CmsContent.php index b6fb806..97de5c6 100644 --- a/app/Models/Sym/CmsContent.php +++ b/app/Models/Sym/CmsContent.php @@ -40,6 +40,7 @@ use Illuminate\Database\Eloquent\Model; * @property int|null $pos * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Sym\CmsContent whereObject($value) * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Sym\CmsContent wherePos($value) + * @method static \Illuminate\Database\Eloquent\Builder|CmsContent withUniqueSlugConstraints(\Illuminate\Database\Eloquent\Model $model, string $attribute, array $config, string $slug) */ class CmsContent extends Model { diff --git a/app/Models/Sym/TravelCountry.php b/app/Models/Sym/TravelCountry.php index 2fab8a2..133ae8d 100644 --- a/app/Models/Sym/TravelCountry.php +++ b/app/Models/Sym/TravelCountry.php @@ -51,6 +51,8 @@ use Illuminate\Database\Eloquent\Model; * @property-read int|null $travel_country_services_count * @property string|null $destco * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\Sym\TravelCountry whereDestco($value) + * @property string|null $visum_text + * @method static \Illuminate\Database\Eloquent\Builder|TravelCountry whereVisumText($value) */ class TravelCountry extends Model { diff --git a/app/Models/TravelCountry.php b/app/Models/TravelCountry.php index f32948f..04c7c23 100644 --- a/app/Models/TravelCountry.php +++ b/app/Models/TravelCountry.php @@ -71,6 +71,8 @@ use Illuminate\Support\Str; * @property-read int|null $travel_country_services_count * @property string|null $destco * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\TravelCountry whereDestco($value) + * @property string|null $visum_text + * @method static \Illuminate\Database\Eloquent\Builder|TravelCountry whereVisumText($value) */ class TravelCountry extends Model { @@ -201,4 +203,13 @@ class TravelCountry extends Model } return ""; } + + public static function getAsNameIdArray($empty = true, $id = 'crm_id'){ + $ret = TravelCountry::get()->pluck('name', $id)->toArray(); + if($empty){ + $first = [null => "-"]; + return $first + $ret; + } + return $ret; + } } \ No newline at end of file diff --git a/app/Models/TravelGuide.php b/app/Models/TravelGuide.php index 637ad01..ea5c1b5 100644 --- a/app/Models/TravelGuide.php +++ b/app/Models/TravelGuide.php @@ -51,6 +51,7 @@ use Illuminate\Database\Eloquent\Model; * @property int|null $author_id * @property-read \App\Models\CMSAuthor|null $author * @method static \Illuminate\Database\Eloquent\Builder|\App\Models\TravelGuide whereAuthorId($value) + * @method static \Illuminate\Database\Eloquent\Builder|TravelGuide withUniqueSlugConstraints(\Illuminate\Database\Eloquent\Model $model, string $attribute, array $config, string $slug) */ class TravelGuide extends Model { diff --git a/app/Models/TravelPlace.php b/app/Models/TravelPlace.php index 356c932..8760963 100644 --- a/app/Models/TravelPlace.php +++ b/app/Models/TravelPlace.php @@ -11,7 +11,7 @@ use Illuminate\Database\Eloquent\Model; /** * Class TravelPlace - * + * * @property int $id * @property string $name * @property string $description @@ -21,10 +21,21 @@ use Illuminate\Database\Eloquent\Model; * @property bool $active * @property Carbon $created_at * @property Carbon $updated_at - * * @property TravelCountry $travel_country - * * @package App\Models + * @method static \Illuminate\Database\Eloquent\Builder|TravelPlace newModelQuery() + * @method static \Illuminate\Database\Eloquent\Builder|TravelPlace newQuery() + * @method static \Illuminate\Database\Eloquent\Builder|TravelPlace query() + * @method static \Illuminate\Database\Eloquent\Builder|TravelPlace whereActive($value) + * @method static \Illuminate\Database\Eloquent\Builder|TravelPlace whereCreatedAt($value) + * @method static \Illuminate\Database\Eloquent\Builder|TravelPlace whereDescription($value) + * @method static \Illuminate\Database\Eloquent\Builder|TravelPlace whereId($value) + * @method static \Illuminate\Database\Eloquent\Builder|TravelPlace whereLatitude($value) + * @method static \Illuminate\Database\Eloquent\Builder|TravelPlace whereLongitude($value) + * @method static \Illuminate\Database\Eloquent\Builder|TravelPlace whereName($value) + * @method static \Illuminate\Database\Eloquent\Builder|TravelPlace whereTravelCountryId($value) + * @method static \Illuminate\Database\Eloquent\Builder|TravelPlace whereUpdatedAt($value) + * @mixin \Eloquent */ class TravelPlace extends Model { diff --git a/app/Models/TravelUserBookingFewo.php b/app/Models/TravelUserBookingFewo.php index 93ad8c1..6f48078 100644 --- a/app/Models/TravelUserBookingFewo.php +++ b/app/Models/TravelUserBookingFewo.php @@ -106,6 +106,8 @@ use App\Services\Util; * @property-read \Illuminate\Database\Eloquent\Collection|\App\Models\TravelUserBookingFile[] $booking_files * @property-read int|null $booking_files_count * @property-read \App\Models\TravelUser $customer + * @property-read \Illuminate\Database\Eloquent\Collection|\App\Models\TravelUserBookingFewoNotice[] $booking_fewo_notices + * @property-read int|null $booking_fewo_notices_count */ class TravelUserBookingFewo extends Model { diff --git a/app/Models/TravelUserBookingFewoNotice.php b/app/Models/TravelUserBookingFewoNotice.php index cce7df0..1d291e6 100644 --- a/app/Models/TravelUserBookingFewoNotice.php +++ b/app/Models/TravelUserBookingFewoNotice.php @@ -12,7 +12,7 @@ use Illuminate\Database\Eloquent\Model; /** * Class TravelUserBookingFewoNotice - * + * * @property int $id * @property int $travel_user_booking_fewo_id * @property int $from_user_id @@ -23,10 +23,24 @@ use Illuminate\Database\Eloquent\Model; * @property Carbon $edit_at * @property Carbon $created_at * @property Carbon $updated_at - * * @property TravelUserBookingFewo $travel_user_booking_fewo - * * @package App\Models + * @property-read User $from_user + * @property-read User|null $to_user + * @method static \Illuminate\Database\Eloquent\Builder|TravelUserBookingFewoNotice newModelQuery() + * @method static \Illuminate\Database\Eloquent\Builder|TravelUserBookingFewoNotice newQuery() + * @method static \Illuminate\Database\Eloquent\Builder|TravelUserBookingFewoNotice query() + * @method static \Illuminate\Database\Eloquent\Builder|TravelUserBookingFewoNotice whereCreatedAt($value) + * @method static \Illuminate\Database\Eloquent\Builder|TravelUserBookingFewoNotice whereEditAt($value) + * @method static \Illuminate\Database\Eloquent\Builder|TravelUserBookingFewoNotice whereFromUserId($value) + * @method static \Illuminate\Database\Eloquent\Builder|TravelUserBookingFewoNotice whereId($value) + * @method static \Illuminate\Database\Eloquent\Builder|TravelUserBookingFewoNotice whereImportant($value) + * @method static \Illuminate\Database\Eloquent\Builder|TravelUserBookingFewoNotice whereMessage($value) + * @method static \Illuminate\Database\Eloquent\Builder|TravelUserBookingFewoNotice whereShow($value) + * @method static \Illuminate\Database\Eloquent\Builder|TravelUserBookingFewoNotice whereToUserId($value) + * @method static \Illuminate\Database\Eloquent\Builder|TravelUserBookingFewoNotice whereTravelUserBookingFewoId($value) + * @method static \Illuminate\Database\Eloquent\Builder|TravelUserBookingFewoNotice whereUpdatedAt($value) + * @mixin \Eloquent */ class TravelUserBookingFewoNotice extends Model { diff --git a/app/Repositories/BookingRepository.php b/app/Repositories/BookingRepository.php index f3d5f7e..372d5f3 100644 --- a/app/Repositories/BookingRepository.php +++ b/app/Repositories/BookingRepository.php @@ -209,6 +209,7 @@ class BookingRepository extends BaseRepository { abort(500); } $fill['participant_pass'] = isset($fill['participant_pass']) ? true : false; + $fill['participant_storno'] = isset($fill['participant_storno']) ? true : false; $fill['participant_child'] = isset($fill['participant_child']) ? true : false; $fill['participant_birthdate'] = isset($fill['participant_birthdate']) ? _reformat_date($fill['participant_birthdate']) : null; $Participant->fill($fill); @@ -223,7 +224,6 @@ class BookingRepository extends BaseRepository { $this->model->participant_birthdate = isset($data['participant_birthdate']) ? _reformat_date($data['participant_birthdate']) : null; $this->model->participant_pass = isset($data['participant_pass']) ? true : false; - $this->model->save(); return $this->model; } diff --git a/app/Repositories/CustomerMailRepository.php b/app/Repositories/CustomerMailRepository.php index 31d9524..5bdd0b3 100644 --- a/app/Repositories/CustomerMailRepository.php +++ b/app/Repositories/CustomerMailRepository.php @@ -243,7 +243,6 @@ class CustomerMailRepository extends BaseRepository { } } } - } foreach ($value->customers as $key=>$val){ $val['email'] = $first_mail; diff --git a/app/Repositories/LeadMailRepository.php b/app/Repositories/LeadMailRepository.php index 07859c4..f399307 100644 --- a/app/Repositories/LeadMailRepository.php +++ b/app/Repositories/LeadMailRepository.php @@ -300,7 +300,7 @@ class LeadMailRepository extends BaseRepository { $value->lead_title_id = " - (".$value->lead->id.")"; $tmp = []; - $tmp['email'] = $lead->customer ? $lead->customer->email : ""; + $tmp['email'] = $lead_mail->customer ? $lead_mail->email : ""; $tmp['name'] = $lead->customer ? $lead->customer->firstname . " " . $lead->customer->name . " | " : "- | "; $tmp['name'] .= $lead->id ? $lead->id. " | " : "- | "; $data['customers'][$lead->id] = $tmp; diff --git a/app/Services/AuthGoogle2FA.php b/app/Services/AuthGoogle2FA.php new file mode 100644 index 0000000..04964af --- /dev/null +++ b/app/Services/AuthGoogle2FA.php @@ -0,0 +1,235 @@ +request = $request; + return $this; + } + + public function init(IlluminateRequest $request) + { + $this->request = $request; + return $this; + } + + public function isAuthenticated() + { + if(!$this->hasSecretKey() || !$this->isEnabled() || $this->noUserIsAuthenticated()){ + return false; + } + if($this->twoFactorAuthStillValid()){ + return true; + } + return ($this->checkOTP() === $this::OTP_VALID); + } + + public function logout() + { + $this->sessionForget(); + } + + public function makeActiveOneTimePasswordResponse() + { + + if($this->request->isMethod('post') && Request::get('action') === 'activate_user_one_time_password'){ + $user = $this->getUser(); + $user->google2fa = true; + $user->save(); + return back(); + } + $MyGoogle2FA = new MyGoogle2FA(); + $MyGoogle2FA->init($this->getUser())->generate(); + $fill = [ + 'MyGoogle2FA' => $MyGoogle2FA, + ]; + $view = view("auth.google2fa_activate", $fill); + return new IlluminateHtmlResponse($view); + + + } + + public function makeRequestOneTimePasswordResponse() + { + $view = view($this->config('view')); + $statusCode = $this->makeStatusCode(); + if ($statusCode !== SymfonyResponse::HTTP_OK) { + $view->withErrors($this->getErrorBagForStatusCode($statusCode)); + } + return new IlluminateHtmlResponse($view, $statusCode); + } + + protected function checkOTP() + { + if (!$this->request->has($this->config('otp_input') )|| empty($this->request->input($this->config('otp_input')))) { + return $this::OTP_EMPTY; + } + + $isValid = $this->verifyOneTimePassword(); + + if ($isValid) { + $this->login(); + return $this::OTP_VALID; + } + return $this::OTP_INVALID; + } + + protected function login() + { + $this->sessionPut($this::SESSION_AUTH_PASSED, true); + } + + protected function verifyOneTimePassword() + { + return Google2FA::verifyKey($this->getGoogle2FASecretKey(), $this->getOneTimePassword()); + } + + private function getOneTimePassword() + { + $password =$this->request->input($this->config('otp_input')); + if (is_null($password) || empty($password)) { + if ($this->config('throw_exceptions', true)) { + throw new \Exception($this->config('error_messages.cannot_be_empty')); } + } + return $password; + } + + private function getGoogle2FASecretKey() + { + return $this->getUser()->{$this->config('otp_secret_column')}; + } + private function hasSecretKey() + { + $secret = $this->getGoogle2FASecretKey(); + return !is_null($secret) && !empty($secret); + } + + private function twoFactorAuthStillValid() + { + return (bool) $this->sessionGet($this::SESSION_AUTH_PASSED, false); + } + + private function isEnabled() + { + return $this->config('enabled'); + } + + private function noUserIsAuthenticated() + { + return is_null($this->getUser()); + } + + private function config($string, $default = null) + { + if (is_null(config($config = $this::CONFIG_PACKAGE_NAME))) { + throw new \Exception("Config ({$config}.php) not found. Have you published it?"); + } + return config( + implode('.', [$this::CONFIG_PACKAGE_NAME, $string]), + $default + ); + } + + private function getAuth() + { + if (is_null($this->auth)) { + $this->auth = app($this->config('auth')); + + if (!empty($this->config('guard'))) { + $this->auth = app($this->config('auth'))->guard($this->config('guard')); + } + } + + return $this->auth; + } + + private function getUser() + { + return $this->getAuth()->user(); + } + + private function makeSessionVarName($name = null) + { + return $this->config('session_var') . (is_null($name) || empty($name) ? '' : '.' . $name); + } + + private function sessionGet($var = null, $default = null) + { + return $this->request->session()->get( + $this->makeSessionVarName($var), + $default + ); + } + + private function sessionPut($var, $value) + { + $this->request->session()->put( + $this->makeSessionVarName($var), + $value + ); + return $value; + } + + private function sessionForget($var = null) + { + $this->request->session()->forget( + $this->makeSessionVarName($var) + ); + } + + private function makeStatusCode() + { + if ($this->request->isMethod('get') || ($this->checkOTP() === $this::OTP_VALID)) { + return SymfonyResponse::HTTP_OK; + } + + if ($this->checkOTP() === $this::OTP_EMPTY) { + return SymfonyResponse::HTTP_BAD_REQUEST; + } + + return SymfonyResponse::HTTP_UNPROCESSABLE_ENTITY; + } + private function getErrorBagForStatusCode($statusCode) + { + $errorMap = [ + SymfonyResponse::HTTP_UNPROCESSABLE_ENTITY => 'google2fa.error_messages.wrong_otp', + SymfonyResponse::HTTP_BAD_REQUEST => 'google2fa.error_messages.cannot_be_empty', + ]; + + return $this->createErrorBagForMessage( + trans( + config( + array_key_exists($statusCode, $errorMap) ? $errorMap[$statusCode] : 'google2fa.error_messages.unknown' + ) + ) + ); + } + private function createErrorBagForMessage($message) + { + return new MessageBag([ + 'message' => $message, + ]); + } +} diff --git a/app/Services/Google2FA.php b/app/Services/Google2FA.php new file mode 100644 index 0000000..64ed181 --- /dev/null +++ b/app/Services/Google2FA.php @@ -0,0 +1,127 @@ +get()->sortByDesc('pos')->pluck('slug', 'id'); + return $booking_email_files; + } + + public static function setOutputDirs($dir, $subdir){ + self::$output_dirs[$dir][] = $subdir; + } + + public static function getMailDirNotInOutput($booking_id, $dir){ + $is_o_dirs = isset(self::$output_dirs[$dir]) ? self::$output_dirs[$dir] : []; + $ret = []; + $CustomerMails = CustomerMail::whereBookingId($booking_id)->whereDir($dir)->get(); + if($CustomerMails){ + foreach($CustomerMails as $CustomerMail){ + if(!in_array($CustomerMail->subdir, $is_o_dirs)){ + $ret[] = $CustomerMail->subdir; + } + } + } + return $ret; + } + + public static function getCustomerMailDirs(){ + $customer_mail_dirs = CMSContent::where('identifier', '=', 'customer-mail-dirs')->get()->sortBy('pos'); + return $customer_mail_dirs; + } + + + public static function getCustomerMailDir($id){ + return CMSContent::where('identifier', '=', 'customer-mail-dirs')->where('pos', '=', $id)->first(); + } + + public static function getCustomerMailName($customer_mail_dir, $mail_dir_id){ + + switch ($customer_mail_dir->getArrayContent('model')){ + case 'TravelCountry': + $model = \App\Models\Sym\TravelCountry::find($mail_dir_id); + break; + case 'Airline': + $model = Airline::find($mail_dir_id); + break; + case 'Insurance': + $model = Insurance::find($mail_dir_id); + break; + case 'TravelCompany': + $model = TravelCompany::find($mail_dir_id); + break; + default: + return ''; + } + + if($model){ + if($customer_mail_dir->getArrayContent('model') === 'TravelCountry'){ + return $model->mail_dir_name; + } + return $model->name; + } + return ""; + } + + public static function getCustomerMailEmails($customer_mail_dir, $mail_dir_id){ + + switch ($customer_mail_dir->getArrayContent('model')){ + case 'TravelCountry': + $model = \App\Models\Sym\TravelCountry::find($mail_dir_id); + break; + case 'Airline': + $model = Airline::find($mail_dir_id); + break; + case 'Insurance': + $model = Insurance::find($mail_dir_id); + break; + case 'TravelCompany': + $model = TravelCompany::find($mail_dir_id); + break; + default: + //direkt from CMSContent + return $customer_mail_dir->getArrayContent('emails'); + } + + if($model){ + return $model->contact_emails; + } + return []; + } + + public static function getBookingInstructionPDFName($fewo){ + return "HINWEISE-FERIENWOHNUNG-".$fewo->pdf_name.".pdf"; + } + + public static function getBookingCMSContent($content, $identifier){ + return CMSContent::where('identifier', '=', $identifier)->where('integer', $content->id)->get()->sortBy('pos'); + } + + public static function getBookingCMSContentForPDF($identifier_content, $identifier){ + $pdf_content = []; + $contents = CMSContent::where('identifier', '=', $identifier_content)->get()->sortBy('pos'); + foreach ($contents as $content){ + if($content->decimal > 0){ //in_pdf + $pdf_content[] = $content; + } + if($fewo_contents = self::getBookingCMSContent($content, $identifier)){ + foreach ($fewo_contents as $fewo_content){ + if($fewo_content->decimal > 0){ //in_pdf + $pdf_content[] = $fewo_content; + } + } + } + } + return $pdf_content; + } +} \ No newline at end of file diff --git a/app/Services/HTMLHelper.php b/app/Services/HTMLHelper.php index 807ab50..98b2505 100644 --- a/app/Services/HTMLHelper.php +++ b/app/Services/HTMLHelper.php @@ -239,7 +239,7 @@ class HTMLHelper $ret = '\n'; } foreach ($options as $option){ - $attr = ($option->id === $setId) ? 'selected="selected"' : ''; + $attr = ($option->id === intval($setId)) ? 'selected="selected"' : ''; $ret .= '\n'; } return $ret; diff --git a/app/Services/MyGoogle2FA.php b/app/Services/MyGoogle2FA.php new file mode 100644 index 0000000..c69432d --- /dev/null +++ b/app/Services/MyGoogle2FA.php @@ -0,0 +1,105 @@ +name = str_replace('https://', '', config('app.url')); + $this->user = $user; + $this->email = $user->email; + return $this; + } + + public function generate() + { + $this->generateSecretKey(); + $this->inlineUrl = $this->getQRCodeInline(); + } + + public function check2Fa($code) + { + if(!$this->getSecretKey()){ + return false; + } + $this->valid = $this->validateInput($code); + return $this->valid; + } + + public function getBy($key){ + return isset($this->{$key}) ? $this->{$key} : ''; + } + + private function getQRCodeInline() + { + return Google2FA::getQRCodeInline( + $this->name, + $this->email, + $this->secretKey + ); + } + private function getSecretKey() + { + if (! $this->secretKey = $this->getStoredKey()) + { + return null; + } + return $this->secretKey; + } + + private function generateSecretKey() + { + if (! $this->secretKey = $this->getStoredKey()) + { + $this->secretKey = Google2FA::generateSecretKey($this->keySize, $this->keyPrefix); + $this->user->secret_key = $this->secretKey; + $this->user->save(); + } + return $this->secretKey; + } + + private function getStoredKey() + { + // No need to read it from disk it again if we already have it + if ($this->secretKey) + { + return $this->secretKey; + } + if(! $this->user->secret_key){ + return null; + } + return $this->user->secret_key; + } + + private function validateInput($code) + { + // Verify the code + return Google2FA::verifyKey($this->secretKey, $code); + } + + public static function logout() + { + (new AuthGoogle2FA(request()))->logout(); + } + +} \ No newline at end of file diff --git a/app/Services/Placeholder.php b/app/Services/Placeholder.php index 76f5aef..648310e 100644 --- a/app/Services/Placeholder.php +++ b/app/Services/Placeholder.php @@ -10,7 +10,7 @@ class Placeholder { public static $placeholder_booking = [ - 'dear' => '#geehrte/r#', + 'dear' => '#geehrte:r#', 'salutation' => '#Anrede#', 'title' => '#Titel#', 'first_name' => '#Vorname#', @@ -26,6 +26,7 @@ class Placeholder 'net_price_travel' => '#Nettopreise_Rundreise#', 'net_price_extra_services' => '#Nettopreise_zugebuchte_Leistungen#', 'booked_rooms' => '#Gebuchte_Zimmer#', + 'myjack_nr' => "#MyJackNr#", 'filekey' => "#Filekey#", 'flight_info' => "#Airline_Fluginfo#", 'check_in' => "#Airline_Checkin#", @@ -35,7 +36,7 @@ class Placeholder ]; public static $placeholder_lead = [ - 'dear' => '#geehrte/r#', + 'dear' => '#geehrte:r#', 'salutation' => '#Anrede#', 'title' => '#Titel#', 'first_name' => '#Vorname#', @@ -49,7 +50,7 @@ class Placeholder ]; public static $placeholder_fewo= [ - 'dear' => '#geehrte/r#', + 'dear' => '#geehrte:r#', 'salutation' => '#Anrede#', 'title' => '#Titel#', 'first_name' => '#Vorname#', @@ -60,6 +61,36 @@ class Placeholder 'booking_date' => '#Buchungsdatum#', ]; + public static function getOptionsSummernote($key){ + /* + [{value:'blockChainId', content:'blockChainId'}, + {value:'attachement', content:'attachement'}, + {value:'address', content:'address'}]*/ + + $ret = ""; + switch ($key) { + case 'booking': + $placehoder = self::$placeholder_booking; + break; + case 'lead': + $placehoder = self::$placeholder_lead; + break; + case 'fewo': + $placehoder = self::$placeholder_fewo; + break; + default: + $placehoder = self::$placeholder_booking; + + break; + + } + foreach ($placehoder as $key => $value) { + $value = str_replace('#', '', $value); + $ret .= "'".$value."',"; + } + return $ret; + } + public static function getOptionsQuill($key){ $ret = ""; switch ($key) { @@ -93,6 +124,7 @@ class Placeholder } return $ret; } + public static function getLeadOptions(){ $ret = ""; foreach (self::$placeholder_lead as $key => $value) { @@ -140,6 +172,8 @@ class Placeholder $net_price_extra_services = self::getBookingPlaceholdersBy('net_price_extra_services', $booking); $booked_rooms = self::getBookingPlaceholdersBy('booked_rooms', $booking); + $myjack_nr = $booking->merlin_order_number; + $participants = "Teilnehmer:
"; //first if($booking->participant_firstname){ @@ -164,10 +198,8 @@ class Placeholder $replace = []; foreach (self::$placeholder_booking as $key => $value) { - if(isset(${$key})){ - $search[] = $value; - $replace[] = ${$key}; - } + $search[] = $value; + $replace[] = isset(${$key}) ? ${$key} : ""; } $content = str_replace($search, $replace, $content); $content = preg_replace('/(.*?)<\/placeholder>/', '$1', $content); @@ -234,11 +266,7 @@ class Placeholder return $content; } - - private static function getBookingPlaceholdersBy($key, $booking){ - - if($booking->new_drafts){ $booked_rooms = ''; $extra_services = ''; @@ -281,7 +309,6 @@ class Placeholder } } - } private static function cleanText($text){ diff --git a/app/User.php b/app/User.php index 40ad762..a1caf0a 100755 --- a/app/User.php +++ b/app/User.php @@ -7,10 +7,11 @@ use App\Models\SfGuardUser; use App\Mail\MailResetPassword; use Laravel\Passport\HasApiTokens; use Illuminate\Support\Facades\Mail; +use Illuminate\Support\Facades\Crypt; use Illuminate\Notifications\Notifiable; use Illuminate\Database\Eloquent\SoftDeletes; use Illuminate\Foundation\Auth\User as Authenticatable; - +use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Distributions\F; /** * App\User @@ -93,7 +94,6 @@ class User extends Authenticatable protected $dates = ['deleted_at']; protected $table = 'users'; - /** * The attributes that are mass assignable. * @@ -109,7 +109,7 @@ class User extends Authenticatable * @var array */ protected $hidden = [ - 'password', 'remember_token', 'token', + 'password', 'remember_token', 'token', 'secret_key', ]; protected $casts = [ @@ -134,6 +134,20 @@ class User extends Authenticatable return $this->hasMany('App\Models\UserUpdateEmail', 'user_id', 'id'); } + public function isGoogle2Fa(){ + return ($this->google2fa && $this->secret_key) ? true : false; + } + + public function setSecretKeyAttribute($value) + { + $this->attributes['secret_key'] = $value ? Crypt::encryptString($value) : null; + } + + public function getSecretKeyAttribute($value) + { + return $value ? Crypt::decryptString($value) : null; + } + /** * @return bool */ @@ -149,6 +163,9 @@ class User extends Authenticatable */ public function isAdmin() { + if(!$this->active){ + return false; + } if($this->admin >= 1){ return true; } @@ -160,6 +177,9 @@ class User extends Authenticatable */ public function isSuperAdmin() { + if(!$this->active){ + return false; + } if($this->admin >= 2){ return true; } @@ -171,6 +191,9 @@ class User extends Authenticatable */ public function isSySAdmin() { + if(!$this->active){ + return false; + } if($this->admin >= 3){ return true; } diff --git a/bootstrap/cache/packages.php b/bootstrap/cache/packages.php index 348ffe0..b8ec015 100755 --- a/bootstrap/cache/packages.php +++ b/bootstrap/cache/packages.php @@ -35,6 +35,28 @@ 0 => 'Cviebrock\\EloquentSluggable\\ServiceProvider', ), ), + 'digital-bird/shoppingcart' => + array ( + 'providers' => + array ( + 0 => 'Gloudemans\\Shoppingcart\\ShoppingcartServiceProvider', + ), + 'aliases' => + array ( + 'Cart' => 'Gloudemans\\Shoppingcart\\Facades\\Cart', + ), + ), + 'facade/ignition' => + array ( + 'providers' => + array ( + 0 => 'Facade\\Ignition\\IgnitionServiceProvider', + ), + 'aliases' => + array ( + 'Flare' => 'Facade\\Ignition\\Facades\\Flare', + ), + ), 'fideloper/proxy' => array ( 'providers' => @@ -42,6 +64,13 @@ 0 => 'Fideloper\\Proxy\\TrustedProxyServiceProvider', ), ), + 'fruitcake/laravel-cors' => + array ( + 'providers' => + array ( + 0 => 'Fruitcake\\Cors\\CorsServiceProvider', + ), + ), 'intervention/image' => array ( 'providers' => @@ -92,6 +121,13 @@ 0 => 'Laravel\\Passport\\PassportServiceProvider', ), ), + 'laravel/sail' => + array ( + 'providers' => + array ( + 0 => 'Laravel\\Sail\\SailServiceProvider', + ), + ), 'laravel/tinker' => array ( 'providers' => @@ -99,6 +135,13 @@ 0 => 'Laravel\\Tinker\\TinkerServiceProvider', ), ), + 'laravel/ui' => + array ( + 'providers' => + array ( + 0 => 'Laravel\\Ui\\UiServiceProvider', + ), + ), 'laravelcollective/html' => array ( 'providers' => @@ -136,6 +179,17 @@ 0 => 'NunoMaduro\\Collision\\Adapters\\Laravel\\CollisionServiceProvider', ), ), + 'pragmarx/google2fa-laravel' => + array ( + 'providers' => + array ( + 0 => 'PragmaRX\\Google2FALaravel\\ServiceProvider', + ), + 'aliases' => + array ( + 'Google2FA' => 'PragmaRX\\Google2FALaravel\\Facade', + ), + ), 'reliese/laravel' => array ( 'providers' => diff --git a/bootstrap/cache/services.php b/bootstrap/cache/services.php index 753df9a..c7f91d4 100755 --- a/bootstrap/cache/services.php +++ b/bootstrap/cache/services.php @@ -27,33 +27,39 @@ 23 => 'Barryvdh\\DomPDF\\ServiceProvider', 24 => 'Barryvdh\\LaravelIdeHelper\\IdeHelperServiceProvider', 25 => 'Cviebrock\\EloquentSluggable\\ServiceProvider', - 26 => 'Fideloper\\Proxy\\TrustedProxyServiceProvider', - 27 => 'Intervention\\Image\\ImageServiceProvider', - 28 => 'IqContent\\LaravelFilemanager\\LaravelFilemanagerServiceProvider', - 29 => 'Jenssegers\\Date\\DateServiceProvider', - 30 => 'Laracasts\\Flash\\FlashServiceProvider', - 31 => 'Laravel\\Passport\\PassportServiceProvider', - 32 => 'Laravel\\Tinker\\TinkerServiceProvider', - 33 => 'Collective\\Html\\HtmlServiceProvider', - 34 => 'Maatwebsite\\Excel\\ExcelServiceProvider', - 35 => 'Carbon\\Laravel\\ServiceProvider', - 36 => 'NunoMaduro\\Collision\\Adapters\\Laravel\\CollisionServiceProvider', - 37 => 'Reliese\\Coders\\CodersServiceProvider', - 38 => 'Yajra\\DataTables\\DataTablesServiceProvider', - 39 => 'Laravel\\Tinker\\TinkerServiceProvider', - 40 => 'Laravel\\Passport\\PassportServiceProvider', - 41 => 'App\\Providers\\AppServiceProvider', - 42 => 'App\\Providers\\AuthServiceProvider', - 43 => 'App\\Providers\\EventServiceProvider', - 44 => 'App\\Providers\\RouteServiceProvider', - 45 => 'Barryvdh\\LaravelIdeHelper\\IdeHelperServiceProvider', - 46 => 'Barryvdh\\DomPDF\\ServiceProvider', - 47 => 'Jenssegers\\Date\\DateServiceProvider', - 48 => 'Collective\\Html\\HtmlServiceProvider', - 49 => 'Intervention\\Image\\ImageServiceProvider', - 50 => 'Maatwebsite\\Excel\\ExcelServiceProvider', - 51 => 'Yajra\\DataTables\\DataTablesServiceProvider', - 52 => 'Reliese\\Coders\\CodersServiceProvider', + 26 => 'Gloudemans\\Shoppingcart\\ShoppingcartServiceProvider', + 27 => 'Facade\\Ignition\\IgnitionServiceProvider', + 28 => 'Fideloper\\Proxy\\TrustedProxyServiceProvider', + 29 => 'Fruitcake\\Cors\\CorsServiceProvider', + 30 => 'Intervention\\Image\\ImageServiceProvider', + 31 => 'IqContent\\LaravelFilemanager\\LaravelFilemanagerServiceProvider', + 32 => 'Jenssegers\\Date\\DateServiceProvider', + 33 => 'Laracasts\\Flash\\FlashServiceProvider', + 34 => 'Laravel\\Passport\\PassportServiceProvider', + 35 => 'Laravel\\Sail\\SailServiceProvider', + 36 => 'Laravel\\Tinker\\TinkerServiceProvider', + 37 => 'Laravel\\Ui\\UiServiceProvider', + 38 => 'Collective\\Html\\HtmlServiceProvider', + 39 => 'Maatwebsite\\Excel\\ExcelServiceProvider', + 40 => 'Carbon\\Laravel\\ServiceProvider', + 41 => 'NunoMaduro\\Collision\\Adapters\\Laravel\\CollisionServiceProvider', + 42 => 'PragmaRX\\Google2FALaravel\\ServiceProvider', + 43 => 'Reliese\\Coders\\CodersServiceProvider', + 44 => 'Yajra\\DataTables\\DataTablesServiceProvider', + 45 => 'Laravel\\Tinker\\TinkerServiceProvider', + 46 => 'Laravel\\Passport\\PassportServiceProvider', + 47 => 'App\\Providers\\AppServiceProvider', + 48 => 'App\\Providers\\AuthServiceProvider', + 49 => 'App\\Providers\\EventServiceProvider', + 50 => 'App\\Providers\\RouteServiceProvider', + 51 => 'Barryvdh\\LaravelIdeHelper\\IdeHelperServiceProvider', + 52 => 'Barryvdh\\DomPDF\\ServiceProvider', + 53 => 'Jenssegers\\Date\\DateServiceProvider', + 54 => 'Collective\\Html\\HtmlServiceProvider', + 55 => 'Intervention\\Image\\ImageServiceProvider', + 56 => 'Maatwebsite\\Excel\\ExcelServiceProvider', + 57 => 'Yajra\\DataTables\\DataTablesServiceProvider', + 58 => 'Reliese\\Coders\\CodersServiceProvider', ), 'eager' => array ( @@ -69,31 +75,34 @@ 9 => 'Illuminate\\View\\ViewServiceProvider', 10 => 'Barryvdh\\Debugbar\\ServiceProvider', 11 => 'Barryvdh\\DomPDF\\ServiceProvider', - 12 => 'Barryvdh\\LaravelIdeHelper\\IdeHelperServiceProvider', - 13 => 'Cviebrock\\EloquentSluggable\\ServiceProvider', - 14 => 'Fideloper\\Proxy\\TrustedProxyServiceProvider', - 15 => 'Intervention\\Image\\ImageServiceProvider', - 16 => 'IqContent\\LaravelFilemanager\\LaravelFilemanagerServiceProvider', - 17 => 'Jenssegers\\Date\\DateServiceProvider', - 18 => 'Laracasts\\Flash\\FlashServiceProvider', - 19 => 'Laravel\\Passport\\PassportServiceProvider', - 20 => 'Maatwebsite\\Excel\\ExcelServiceProvider', - 21 => 'Carbon\\Laravel\\ServiceProvider', - 22 => 'NunoMaduro\\Collision\\Adapters\\Laravel\\CollisionServiceProvider', - 23 => 'Reliese\\Coders\\CodersServiceProvider', - 24 => 'Yajra\\DataTables\\DataTablesServiceProvider', - 25 => 'Laravel\\Passport\\PassportServiceProvider', - 26 => 'App\\Providers\\AppServiceProvider', - 27 => 'App\\Providers\\AuthServiceProvider', - 28 => 'App\\Providers\\EventServiceProvider', - 29 => 'App\\Providers\\RouteServiceProvider', - 30 => 'Barryvdh\\LaravelIdeHelper\\IdeHelperServiceProvider', - 31 => 'Barryvdh\\DomPDF\\ServiceProvider', - 32 => 'Jenssegers\\Date\\DateServiceProvider', - 33 => 'Intervention\\Image\\ImageServiceProvider', - 34 => 'Maatwebsite\\Excel\\ExcelServiceProvider', - 35 => 'Yajra\\DataTables\\DataTablesServiceProvider', - 36 => 'Reliese\\Coders\\CodersServiceProvider', + 12 => 'Cviebrock\\EloquentSluggable\\ServiceProvider', + 13 => 'Gloudemans\\Shoppingcart\\ShoppingcartServiceProvider', + 14 => 'Facade\\Ignition\\IgnitionServiceProvider', + 15 => 'Fideloper\\Proxy\\TrustedProxyServiceProvider', + 16 => 'Fruitcake\\Cors\\CorsServiceProvider', + 17 => 'Intervention\\Image\\ImageServiceProvider', + 18 => 'IqContent\\LaravelFilemanager\\LaravelFilemanagerServiceProvider', + 19 => 'Jenssegers\\Date\\DateServiceProvider', + 20 => 'Laracasts\\Flash\\FlashServiceProvider', + 21 => 'Laravel\\Passport\\PassportServiceProvider', + 22 => 'Laravel\\Ui\\UiServiceProvider', + 23 => 'Maatwebsite\\Excel\\ExcelServiceProvider', + 24 => 'Carbon\\Laravel\\ServiceProvider', + 25 => 'NunoMaduro\\Collision\\Adapters\\Laravel\\CollisionServiceProvider', + 26 => 'PragmaRX\\Google2FALaravel\\ServiceProvider', + 27 => 'Reliese\\Coders\\CodersServiceProvider', + 28 => 'Yajra\\DataTables\\DataTablesServiceProvider', + 29 => 'Laravel\\Passport\\PassportServiceProvider', + 30 => 'App\\Providers\\AppServiceProvider', + 31 => 'App\\Providers\\AuthServiceProvider', + 32 => 'App\\Providers\\EventServiceProvider', + 33 => 'App\\Providers\\RouteServiceProvider', + 34 => 'Barryvdh\\DomPDF\\ServiceProvider', + 35 => 'Jenssegers\\Date\\DateServiceProvider', + 36 => 'Intervention\\Image\\ImageServiceProvider', + 37 => 'Maatwebsite\\Excel\\ExcelServiceProvider', + 38 => 'Yajra\\DataTables\\DataTablesServiceProvider', + 39 => 'Reliese\\Coders\\CodersServiceProvider', ), 'deferred' => array ( @@ -103,16 +112,20 @@ 'Illuminate\\Bus\\Dispatcher' => 'Illuminate\\Bus\\BusServiceProvider', 'Illuminate\\Contracts\\Bus\\Dispatcher' => 'Illuminate\\Bus\\BusServiceProvider', 'Illuminate\\Contracts\\Bus\\QueueingDispatcher' => 'Illuminate\\Bus\\BusServiceProvider', + 'Illuminate\\Bus\\BatchRepository' => 'Illuminate\\Bus\\BusServiceProvider', 'cache' => 'Illuminate\\Cache\\CacheServiceProvider', 'cache.store' => 'Illuminate\\Cache\\CacheServiceProvider', 'cache.psr6' => 'Illuminate\\Cache\\CacheServiceProvider', 'memcached.connector' => 'Illuminate\\Cache\\CacheServiceProvider', + 'Illuminate\\Cache\\RateLimiter' => 'Illuminate\\Cache\\CacheServiceProvider', 'command.cache.clear' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', 'command.cache.forget' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', 'command.clear-compiled' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', 'command.auth.resets.clear' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', 'command.config.cache' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', 'command.config.clear' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'Illuminate\\Database\\Console\\DbCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'command.db.prune' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', 'command.db.wipe' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', 'command.down' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', 'command.environment' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', @@ -123,26 +136,36 @@ 'command.optimize' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', 'command.optimize.clear' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', 'command.package.discover' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', - 'command.preset' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'command.queue.clear' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', 'command.queue.failed' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', 'command.queue.flush' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', 'command.queue.forget' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', 'command.queue.listen' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'command.queue.monitor' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'command.queue.prune-batches' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'command.queue.prune-failed-jobs' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', 'command.queue.restart' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', 'command.queue.retry' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'command.queue.retry-batch' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', 'command.queue.work' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', 'command.route.cache' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', 'command.route.clear' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', 'command.route.list' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'command.schema.dump' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', 'command.seed' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', 'Illuminate\\Console\\Scheduling\\ScheduleFinishCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'Illuminate\\Console\\Scheduling\\ScheduleListCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', 'Illuminate\\Console\\Scheduling\\ScheduleRunCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'Illuminate\\Console\\Scheduling\\ScheduleTestCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'Illuminate\\Console\\Scheduling\\ScheduleWorkCommand' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', 'command.storage.link' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', 'command.up' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', 'command.view.cache' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', 'command.view.clear' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', 'command.cache.table' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'command.cast.make' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', 'command.channel.make' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'command.component.make' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', 'command.console.make' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', 'command.controller.make' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', 'command.event.generate' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', @@ -161,12 +184,14 @@ 'command.provider.make' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', 'command.queue.failed-table' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', 'command.queue.table' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'command.queue.batches-table' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', 'command.request.make' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', 'command.resource.make' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', 'command.rule.make' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', 'command.seeder.make' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', 'command.session.table' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', 'command.serve' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', + 'command.stub.publish' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', 'command.test.make' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', 'command.vendor.publish' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', 'migrator' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', @@ -183,16 +208,15 @@ 'composer' => 'Illuminate\\Foundation\\Providers\\ConsoleSupportServiceProvider', 'hash' => 'Illuminate\\Hashing\\HashServiceProvider', 'hash.driver' => 'Illuminate\\Hashing\\HashServiceProvider', + 'mail.manager' => 'Illuminate\\Mail\\MailServiceProvider', 'mailer' => 'Illuminate\\Mail\\MailServiceProvider', - 'swift.mailer' => 'Illuminate\\Mail\\MailServiceProvider', - 'swift.transport' => 'Illuminate\\Mail\\MailServiceProvider', 'Illuminate\\Mail\\Markdown' => 'Illuminate\\Mail\\MailServiceProvider', 'Illuminate\\Contracts\\Pipeline\\Hub' => 'Illuminate\\Pipeline\\PipelineServiceProvider', 'queue' => 'Illuminate\\Queue\\QueueServiceProvider', - 'queue.worker' => 'Illuminate\\Queue\\QueueServiceProvider', - 'queue.listener' => 'Illuminate\\Queue\\QueueServiceProvider', - 'queue.failer' => 'Illuminate\\Queue\\QueueServiceProvider', 'queue.connection' => 'Illuminate\\Queue\\QueueServiceProvider', + 'queue.failer' => 'Illuminate\\Queue\\QueueServiceProvider', + 'queue.listener' => 'Illuminate\\Queue\\QueueServiceProvider', + 'queue.worker' => 'Illuminate\\Queue\\QueueServiceProvider', 'redis' => 'Illuminate\\Redis\\RedisServiceProvider', 'redis.connection' => 'Illuminate\\Redis\\RedisServiceProvider', 'auth.password' => 'Illuminate\\Auth\\Passwords\\PasswordResetServiceProvider', @@ -201,6 +225,10 @@ 'translation.loader' => 'Illuminate\\Translation\\TranslationServiceProvider', 'validator' => 'Illuminate\\Validation\\ValidationServiceProvider', 'validation.presence' => 'Illuminate\\Validation\\ValidationServiceProvider', + 'command.ide-helper.generate' => 'Barryvdh\\LaravelIdeHelper\\IdeHelperServiceProvider', + 'command.ide-helper.models' => 'Barryvdh\\LaravelIdeHelper\\IdeHelperServiceProvider', + 'Laravel\\Sail\\Console\\InstallCommand' => 'Laravel\\Sail\\SailServiceProvider', + 'Laravel\\Sail\\Console\\PublishCommand' => 'Laravel\\Sail\\SailServiceProvider', 'command.tinker' => 'Laravel\\Tinker\\TinkerServiceProvider', 'html' => 'Collective\\Html\\HtmlServiceProvider', 'form' => 'Collective\\Html\\HtmlServiceProvider', @@ -245,6 +273,12 @@ 'Illuminate\\Validation\\ValidationServiceProvider' => array ( ), + 'Barryvdh\\LaravelIdeHelper\\IdeHelperServiceProvider' => + array ( + ), + 'Laravel\\Sail\\SailServiceProvider' => + array ( + ), 'Laravel\\Tinker\\TinkerServiceProvider' => array ( ), diff --git a/composer.json b/composer.json index c2932d4..02e2ce5 100755 --- a/composer.json +++ b/composer.json @@ -14,35 +14,41 @@ } ], "require": { - "php": "^7.2", - "barryvdh/laravel-dompdf": "^0.8.5", - "setasign/fpdf": "1.8.*", - "setasign/fpdi": "^2.0", + + "php": "^7.3|^8.0", + "barryvdh/laravel-dompdf": "*", "cviebrock/eloquent-sluggable": "*", + "digital-bird/shoppingcart": "^3.0", "doctrine/dbal": "*", - "fideloper/proxy": "*", - "guzzlehttp/guzzle": "*", + "fideloper/proxy": "^4.4", + "fruitcake/laravel-cors": "^2.0", + "guzzlehttp/guzzle": "^7.0.1", "intervention/image": "*", - "iqcontent/laravel-filemanager": "*", "jenssegers/date": "*", "laracasts/flash": "*", - "laravel/framework": "^6.0", - "laravel/helpers": "^1.1", + "laravel/framework": "^8.12", + "laravel/helpers": "*", "laravel/passport": "*", - "laravel/tinker": "*", + "laravel/tinker": "^2.5", + "laravel/ui": "^3.1", "laravelcollective/html": "*", - "maatwebsite/excel": "^3.1", "reliese/laravel": "*", - "yajra/laravel-datatables-oracle": "*" + "rguedes/pdfmerger": "^1.0", + "setasign/fpdf": "*", + "setasign/fpdi": "*", + "yajra/laravel-datatables-oracle": "*", + "iqcontent/laravel-filemanager": "*", + "maatwebsite/excel": "^3.1" }, "require-dev": { - "barryvdh/laravel-debugbar": "^3.2", - "barryvdh/laravel-ide-helper": "*", - "filp/whoops": "*", - "fzaninotto/faker": "*", - "mockery/mockery": "*", - "nunomaduro/collision": "*", - "phpunit/phpunit": "*" + "facade/ignition": "^2.5", + "fakerphp/faker": "^1.9.1", + "laravel/sail": "^1.0.1", + "mockery/mockery": "^1.4.2", + "nunomaduro/collision": "^5.0", + "phpunit/phpunit": "^9.3.3", + "barryvdh/laravel-debugbar": "*", + "barryvdh/laravel-ide-helper": "*" }, "autoload": { "files": [ @@ -87,9 +93,9 @@ ] }, "config": { + "optimize-autoloader": true, "preferred-install": "dist", - "sort-packages": true, - "optimize-autoloader": true + "sort-packages": true }, "minimum-stability": "dev", "prefer-stable": true diff --git a/config/google2fa.php b/config/google2fa.php new file mode 100644 index 0000000..4209955 --- /dev/null +++ b/config/google2fa.php @@ -0,0 +1,83 @@ + env('OTP_ENABLED', true), + + /* + * Lifetime in minutes. + * + * In case you need your users to be asked for a new one time passwords from time to time. + */ + 'lifetime' => env('OTP_LIFETIME', 0), // 0 = eternal + + /* + * Renew lifetime at every new request. + */ + 'keep_alive' => env('OTP_KEEP_ALIVE', true), + + /* + * Auth container binding. + */ + 'auth' => 'auth', + + /* + * Guard. + */ + 'guard' => '', + + /* + * 2FA verified session var. + */ + 'session_var' => 'google2fa', + + /* + * One Time Password request input name. + */ + 'otp_input' => 'one_time_password', + + /* + * One Time Password Window. + */ + 'window' => 1, + + /* + * Forbid user to reuse One Time Passwords. + */ + 'forbid_old_passwords' => false, + + /* + * User's table column for google2fa secret. + */ + 'otp_secret_column' => 'secret_key', + + /* + * One Time Password View. + */ + 'view' => 'auth.google2fa', + + /* + * One Time Password error message. + */ + 'error_messages' => [ + 'wrong_otp' => "Das 'One Time Password' ist falsch.", + 'cannot_be_empty' => "Das 'One Time Password' kann nicht leer sein.", + 'unknown' => "Ein unbekannter Fehler ist aufgetreten. Bitte versuche es erneut.", + ], + + /* + * Throw exceptions or just fire events? + */ + 'throw_exceptions' => env('OTP_THROW_EXCEPTION', true), + + /* + * Which image backend to use for generating QR codes? + * + * Supports imagemagick, svg and eps + */ + 'qrcode_image_backend' => \PragmaRX\Google2FALaravel\Support\Constants::QRCODE_IMAGE_BACKEND_SVG, + +]; diff --git a/database/migrations/2014_10_12_000000_create_users_table.php b/database/migrations/2014_10_12_000000_create_users_table.php index 1cc2ab9..013b79d 100755 --- a/database/migrations/2014_10_12_000000_create_users_table.php +++ b/database/migrations/2014_10_12_000000_create_users_table.php @@ -18,6 +18,8 @@ class CreateUsersTable extends Migration $table->string('name'); $table->string('email')->unique(); $table->string('password'); + $table->string('secret_key', 50); + $table->boolean('google2fa')->default(false); $table->boolean('confirmed')->default(false); $table->string('confirmation_code', 30)->index()->nullable(); diff --git a/database/migrations/2020_01_29_152709_create_participant_table.php b/database/migrations/2020_01_29_152709_create_participant_table.php index c1220d1..57d6c99 100644 --- a/database/migrations/2020_01_29_152709_create_participant_table.php +++ b/database/migrations/2020_01_29_152709_create_participant_table.php @@ -26,8 +26,9 @@ class CreateParticipantTable extends Migration $table->bigInteger('participant_salutation_id')->nullable(); $table->tinyInteger('participant_child')->nullable()->default(0); $table->tinyInteger('participant_pass')->nullable()->default(0); + $table->tinyInteger('participant_storno')->nullable()->default(0); $table->unsignedInteger('nationality_id')->nullable(); - + $table->index('booking_id', 'participant_booking_id_idx'); $table->index('participant_salutation_id', 'participant_participant_salutation_id_idx'); diff --git a/packages/iqcontent/laravel-filemanager/composer.json b/packages/iqcontent/laravel-filemanager/composer.json index 20a8b9c..8da1b2c 100644 --- a/packages/iqcontent/laravel-filemanager/composer.json +++ b/packages/iqcontent/laravel-filemanager/composer.json @@ -19,16 +19,17 @@ } ], "require": { - "php": ">=7.1.3", + "php": ">=7.2.0", "ext-exif": "*", "ext-fileinfo": "*", "intervention/image": "2.*", - "illuminate/config": "5.4.* || 5.5.* || 5.6.* || 5.7.* || 5.8.* || ^6.0", - "illuminate/filesystem": "5.4.* || 5.5.* || 5.6.* || 5.7.* || 5.8.* || ^6.0", - "illuminate/support": "5.4.* || 5.5.* || 5.6.* || 5.7.* || 5.8.* || ^6.0", - "illuminate/http": "5.4.* || 5.5.* || 5.6.* || 5.7.* || 5.8.* || ^6.0", - "illuminate/container": "5.4.* || 5.5.* || 5.6.* || 5.7.* || 5.8.* || ^6.0", + "illuminate/config": "5.4.* || 5.5.* || 5.6.* || 5.7.* || 5.8.* || ^6.0 || ^7.0 || ^8.0", + "illuminate/filesystem": "5.4.* || 5.5.* || 5.6.* || 5.7.* || 5.8.* || ^6.0 || ^7.0 || ^8.0", + "illuminate/support": "5.4.* || 5.5.* || 5.6.* || 5.7.* || 5.8.* || ^6.0 || ^7.0 || ^8.0", + "illuminate/http": "5.4.* || 5.5.* || 5.6.* || 5.7.* || 5.8.* || ^6.0 || ^7.0 || ^8.0", + "illuminate/container": "5.4.* || 5.5.* || 5.6.* || 5.7.* || 5.8.* || ^6.0 || ^7.0 || ^8.0", "cviebrock/eloquent-sluggable": "*" + }, "require-dev": { "phpunit/phpunit": "^6.2", diff --git a/public/js/custom.js b/public/js/custom.js index c019cb5..f7376f2 100644 --- a/public/js/custom.js +++ b/public/js/custom.js @@ -279,46 +279,6 @@ function ajax_object_action(event, object, callback) { return false; } -function update_modal_data_show(e, $ele) { - e.preventDefault(); - - var ele = $ele, - url = ele.data('url'), - data = {id:ele.data('data')} , - contentType = 'application/x-www-form-urlencoded; charset=UTF-8'; - - /* console.log(data); - console.log(url);*/ - $.ajax({ - url: url, - data: data, - type: "POST", - dataType: "html", - cache: false, - contentType: contentType, - encode: true, - headers: { - 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') - }, - success: function(data) { - // do what ever you want here. add content to
if it was not 1 . - //console.log(data); - $('#update-modal-content').html(data); - $('.selectpicker').selectpicker(["refresh"]); - $('.input-daterange').datepicker({toggleActive: true,format: 'dd.mm.yyyy'}); - // $.Nestable.init(); - $('#updateModalShow').modal('show'); - }, - error: function(xhr, status, errorThrown) { - console.log(xhr); - console.log(xhr.responseText); - console.log(status); - console.log("Sorry, there was a problem!"); - } - }); - return false; -} - function update_modal_data_load(e, $ele) { var ele = $ele, url = ele.data('url'), diff --git a/public/js/summernote-iq-content-placeholders.js b/public/js/summernote-iq-content-placeholders.js new file mode 100644 index 0000000..c2080e2 --- /dev/null +++ b/public/js/summernote-iq-content-placeholders.js @@ -0,0 +1,269 @@ +(function(factory) +{ + /* global define */ + if (typeof define === 'function' && define.amd) + { + // AMD. Register as an anonymous module. + define(['jquery'], factory); + } + else if (typeof module === 'object' && module.exports) + { + // Node/CommonJS + module.exports = factory(require('jquery')); + } + else + { + // Browser globals + factory(window.jQuery); + } +}(function($) +{ + + // Extends plugins for adding gallery. + // - plugin is external module for customizing. + $.extend($.summernote.plugins, + { + /** + * @param {Object} context - context object has status of editor. + */ + 'gallery': function(context) + { + var self = this; + + // ui has renders to build ui elements. + // - you can create a button with `ui.button` + var ui = $.summernote.ui; + + // add gallery button + context.memo('button.gallery', function() + { + // create button + var button = ui.button( + { + contents: '', + tooltip: 'Medien', + click: function() + { + self.fillModal(); + self.$modal.modal(); + } + }); + + // create jQuery object from button instance. + $gallery = button.render(); + return $gallery; + }); + + // This events will be attached when editor is initialized. + this.events = { + // This will be called after modules are initialized. + 'summernote.init': function(we, e) + { + self.editable = context.layoutInfo.editable; //contentEditable element + self.editor = this; + // get summernote onInit set parameters + self.image_dialog_images_url = $(this).data('image_dialog_images_url'); + self.image_dialog_images_html = $(this).data('image_dialog_images_html'); + self.image_dialog_title = $(this).data('image_dialog_title'); + self.image_dialog_close_btn_text = $(this).data('image_dialog_close_btn_text'); + self.image_dialog_ok_btn_text = $(this).data('image_dialog_ok_btn_text'); + + self.fillModal = function() + { + //fill modal with images whether from url or given html + if (typeof self.image_dialog_images_html !== "undefined") + { + self.setModalHtml(self.image_dialog_images_html) + self.setEvents(); + } + else if (typeof self.image_dialog_images_url !== "undefined") + { + var next = self.setEvents; + self.getImagesFromUrl(next); + } + else + { + console.error("options image_dialog_images_html or image_dialog_images_url must be set"); + } + + }; + self.setModalHtml = function(html) + { // set variabl parts to modal html + var title = self.image_dialog_title; + var close = self.image_dialog_close_btn_text; + var ok = self.image_dialog_ok_btn_text; + + if (self.image_dialog_title !== "undefined") self.$modal.find('.modal-title').html(title); + if (self.image_dialog_close_btn_text !== "undefined") self.$modal.find('#modal_iq_close').html(close); + if (self.image_dialog_ok_btn_text !== "undefined") self.$modal.find('#modal_iq_save').html(ok); + + self.$modal.find('.modal-body').html(html); + LFileManager.initFileManager(true); + + }; + self.getImagesFromUrl = function(callback) + { + // get images html from url + $.get(self.image_dialog_images_url, function(html) + { + self.setModalHtml(html); + callback(); + + }).fail(function() + { + console.error("error loading from "+self.image_dialog_images_url); + }) + }; + self.setEvents = function() + { + // images click event to select image + /*self.$modal.find('img').click(function(event) + { + // $(this).toggleClass(self.select_class); + });*/ + }; + // set the focus to the last focused element in the editor + self.recoverEditorFocus = function () + { + var last_focused_el = $(self.editor).data('last_focused_element'); + if(typeof last_focused_el !== "undefined") + { + var editor = self.editable; + var range = document.createRange(); + var sel = window.getSelection(); + var cursor_position = last_focused_el.length; + + range.setStart(last_focused_el, cursor_position); + range.collapse(true); + sel.removeAllRanges(); + sel.addRange(range); + editor.focus(); + } + }; + self.saveLastFocusedElement = function() + { + var focused_element = window.getSelection().focusNode; + var parent = $(self.editable).get(0); + if ($.contains(parent, focused_element)) + { + $(self.editor).data('last_focused_element', focused_element) + } + }; + self.editorEvents = function () { + $(self.editable).on('keypress, mousemove', function() + { + self.saveLastFocusedElement(); + }) + }; + self.editorEvents(); + self.fillModal(); + }, + // This will be called when user releases a key on editable. + 'summernote.keyup': function(we, e) + { + self.saveLastFocusedElement(); + } + }; + + // This method will be called when editor is initialized by $('..').summernote(); + // You can create elements for plugin + this.initialize = function() + { + var $modal = this.$modal = $('#modal_iq_assets').hide(); + // add selected images to summernote editor + $modal.find("button#modal_iq_save").click(function(event) + { + var items = LFileManager.getSelectedItems(); + + $modal.modal('hide'); + + self.recoverEditorFocus(); + + items.forEach(function (item, index) { + var insert = self.insertHTML(item); + if(insert){ + context.invoke('editor.pasteHTML', insert); + } + }); + }); + + }; + + + this.insertHTML = function(item){ + var title = 'Bildtitel ...'; + var description = ''; + var author_name = ''; + var img_title = ''; + + if(item.content !== null){ + if(item.content.title !== undefined && item.content.title){ + title = item.content.title; + img_title = item.content.title; + } + if(item.content.description !== undefined && item.content.description){ + description = ' ' + item.content.description; + } + if(item.content.author_name !== undefined && item.content.author_name){ + author_name = 'Bildquelle: ' + item.content.author_name; + if(img_title !== ''){ + img_title = img_title + " | " + author_name; + }else{ + img_title = author_name; + } + + } + } + // console.log(item) + var insert = ''; + + if(item.is_file && item.is_image){ + insert += '
'+ + ''+title+'' + + '
\n' + + '

' + title + '

\n' + + '
\n' + + '
'; + return insert; + } + if(item.icon === "fab fa-youtube-square"){ + + + insert += '
\n' + + '

'+ title +'

\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '
\n' + + '\n' + + '
\n' + + '
\n' + + '

' + description + '

\n' + + '
\n' + + '
'; + + return insert; + } + if(item.is_file){ + insert += ''+item.name+''; + if(description !== ''){ + insert += '

'+description+'

'; + } + return insert; + } + + return false; + }; + + // This methods will be called when editor is destroyed by $('..').summernote('destroy'); + // You should remove elements on `initialize`. + this.destroy = function() + { + console.log("destroy"); + // this.$panel.remove(); + // this.$panel = null; + }; + } + }); +})); diff --git a/public/js/summernote-placeholders.js b/public/js/summernote-placeholders.js new file mode 100644 index 0000000..301a291 --- /dev/null +++ b/public/js/summernote-placeholders.js @@ -0,0 +1,112 @@ +(function(factory) +{ + /* global define */ + if (typeof define === 'function' && define.amd) + { + // AMD. Register as an anonymous module. + define(['jquery'], factory); + } + else if (typeof module === 'object' && module.exports) + { + // Node/CommonJS + module.exports = factory(require('jquery')); + } + else + { + // Browser globals + factory(window.jQuery); + } +}(function($) +{ + + // Extends plugins for adding gallery. + // - plugin is external module for customizing. + $.extend($.summernote.plugins, + { + /** + * @param {Object} context - context object has status of editor. + */ + 'placeholders': function(context) + { + var self = this; + + var options = context.options.placeholderList; + var defaultOptions = { + label: "Platzhalter", + tooltip: "Platzhalter einfügen", + blockChar : '#', + }; + for (var propertyName in defaultOptions) { + if (options && propertyName && options.hasOwnProperty(propertyName) === false) { + options[propertyName] = defaultOptions[propertyName]; + } + } + var ui = $.summernote.ui; + + // add gallery button + context.memo('button.placeholders', function() + { + + var placeholdersButton = ui.buttonGroup([ + ui.button({ + className: 'dropdown-toggle', + contents: ' ' + options.label + ' ', + tooltip: options.tooltip, + data: { + toggle: 'dropdown' + }, + click: function () { + console.log('placeholders button click'); + context.invoke('editor.saveRange'); + } + }), + ui.dropdown({ + className: 'dropdown-style', + items: options.items, + callback: function($dropdown) { + //console.log('$dropdown callback'); + }, + click: function (event) { + event.preventDefault(); + var $button = $(event.target); + var value = $button.data('value'); + var text = options.blockChar + value + options.blockChar; + context.invoke('editor.insertText', text); + //console.log('$dropdown click : ' + options.blockChar + value + options.blockChar); + }, + template: function(item) + { + var content = (typeof item === 'string') ? item : (item.content || item.value || ''); + return content; + } + }) + ]).render(); + return placeholdersButton; + }); + + // This events will be attached when editor is initialized. + this.events = { + // This will be called after modules are initialized. + 'summernote.init': function(we, e) { + + //console.log('summernote initialized', we, e); + }, + // This will be called when user releases a key on editable. + 'summernote.keyup': function(we, e) { + + //console.log('summernote keyup', we, e); + } + + }; + + // This methods will be called when editor is destroyed by $('..').summernote('destroy'); + // You should remove elements on `initialize`. + this.destroy = function() + { + console.log("destroy"); + // this.$panel.remove(); + // this.$panel = null; + }; + } + }); +})); diff --git a/resources/lang/de/validation.php b/resources/lang/de/validation.php index 791d09e..bcf5258 100755 --- a/resources/lang/de/validation.php +++ b/resources/lang/de/validation.php @@ -113,6 +113,7 @@ return [ 'url' => ':attribute muss eine URL sein.', 'old_password' => 'Passwort ist nicht gültig', 'users_update_email' => 'Die E-Mail ist schon zur Änderung eingetragen', + 'usernotactive' => 'Konto ist nicht aktiv', /* |-------------------------------------------------------------------------- diff --git a/resources/views/admin/active_modal.blade.php b/resources/views/admin/active_modal.blade.php new file mode 100644 index 0000000..84864b8 --- /dev/null +++ b/resources/views/admin/active_modal.blade.php @@ -0,0 +1,31 @@ + + +{!! Form::open(['url' => route('admin_user_update_modal', [$action]), 'class' => 'form-horizontal']) !!} + + + +{!! Form::close() !!} \ No newline at end of file diff --git a/resources/views/admin/google2fa__modal.blade.php b/resources/views/admin/google2fa__modal.blade.php new file mode 100644 index 0000000..8927c08 --- /dev/null +++ b/resources/views/admin/google2fa__modal.blade.php @@ -0,0 +1,60 @@ + + +{!! Form::open(['url' => route('admin_user_update_modal', [$action]), 'class' => 'form-horizontal']) !!} + + + +{!! Form::close() !!} \ No newline at end of file diff --git a/resources/views/admin/google2fa_delete_modal.blade.php b/resources/views/admin/google2fa_delete_modal.blade.php new file mode 100644 index 0000000..0275552 --- /dev/null +++ b/resources/views/admin/google2fa_delete_modal.blade.php @@ -0,0 +1,35 @@ + + +{!! Form::open(['url' => route('admin_user_update_modal', [$action]), 'class' => 'form-horizontal']) !!} + + +{!! Form::close() !!} \ No newline at end of file diff --git a/resources/views/admin/google2fa_modal.blade.php b/resources/views/admin/google2fa_modal.blade.php new file mode 100644 index 0000000..07fc81f --- /dev/null +++ b/resources/views/admin/google2fa_modal.blade.php @@ -0,0 +1,41 @@ + + +{!! Form::open(['url' => route('admin_user_update_modal', [$action]), 'class' => 'form-horizontal']) !!} + + +{!! Form::close() !!} \ No newline at end of file diff --git a/resources/views/admin/modal/cms_booking_content_edit.blade.php b/resources/views/admin/modal/cms_booking_content_edit.blade.php new file mode 100644 index 0000000..4dc8238 --- /dev/null +++ b/resources/views/admin/modal/cms_booking_content_edit.blade.php @@ -0,0 +1,57 @@ + + + diff --git a/resources/views/admin/user_form.blade.php b/resources/views/admin/user_form.blade.php index 1a0fa9b..802302a 100644 --- a/resources/views/admin/user_form.blade.php +++ b/resources/views/admin/user_form.blade.php @@ -22,14 +22,6 @@ {{ Form::text('email-confirm', $user->email, array('placeholder'=>__('Confirm E-Mail'), 'class'=>'form-control', 'id'=>'email-confirm', 'readonly'=>true)) }}
- @if(isset($isFromAdmin)) - @if(count($user->user_update_email) > 0) -

{{ $user->user_update_email->first()->email }} {{__('waiting for activation since')}} | {{ $user->user_update_email->first()->created_at->format('d.m.Y H:i') }}


- @endif - {{ __('Contact') }} {{__('Change E-Mail')}} - @else - {{__('Change E-Mail')}} - @endif @else
diff --git a/resources/views/admin/user_modal.blade.php b/resources/views/admin/user_modal.blade.php index 62c5a73..6351a17 100644 --- a/resources/views/admin/user_modal.blade.php +++ b/resources/views/admin/user_modal.blade.php @@ -1,12 +1,13 @@ -{!! Form::open(['url' => route('admin_user_update_modal', ['user']), 'class' => 'form-horizontal']) !!} +{!! Form::open(['url' => route('admin_user_update_modal', [$action]), 'class' => 'form-horizontal']) !!} +@endsection + + +@section('scripts') + + + @endsection \ No newline at end of file diff --git a/resources/views/cms/booking/content/index.blade.php b/resources/views/cms/booking/content/index.blade.php index 22b8eb8..03cadf9 100755 --- a/resources/views/cms/booking/content/index.blade.php +++ b/resources/views/cms/booking/content/index.blade.php @@ -27,6 +27,9 @@   {{__('Name')}} {{__('Vorlage')}} + {{__('Länder')}} + {{__('auto')}} + {{__('aktiv')}} {{__('')}} @@ -39,15 +42,19 @@ - {{ $value->name }}   - - - +  {{ $value->name }} {{ \App\Services\Model::getCMSContentGeneralNameById($value->getObjectBy('general_id')) }} + x + x + x @@ -58,50 +65,17 @@
- +
- - - - - - diff --git a/resources/views/lead/modal-show-mail-inner.blade.php b/resources/views/lead/modal-show-mail-inner.blade.php index 4b99764..16dfda2 100644 --- a/resources/views/lead/modal-show-mail-inner.blade.php +++ b/resources/views/lead/modal-show-mail-inner.blade.php @@ -11,8 +11,12 @@ @if($lead_mail->is_answer) Antwort von:
@else - Gesendet an:
+ @if($lead_mail->send) + Gesendet an:
+ @else + (nicht gesendet) an:
@endif + @endif <{{$lead_mail->email}}> {{$lead_mail->sent_at }} @if($lead_mail->recipient)
TO: {{\App\Services\Util::_implodeLines($lead_mail->recipient, ', ')}}
diff --git a/resources/views/mails/booking.blade.php b/resources/views/mails/booking.blade.php index a821e93..15c6c62 100644 --- a/resources/views/mails/booking.blade.php +++ b/resources/views/mails/booking.blade.php @@ -10,14 +10,12 @@   - {{__('BuchungID')}} {{__('Vorname')}} {{__('Nachname')}} {{__('E-Mail')}} {{__('Betreff')}} {{__('Buchung')}} - {{__('gesendet')}} {{__('Datum')}} @@ -30,17 +28,15 @@ "processing": true, "serverSide": true, "ajax": '{!! route('mail_booking_datatable') !!}', - "order": [[ 8, "desc" ]], + "order": [[ 7, "desc" ]], "columns": [ { data: 'action_edit', orderable: false, searchable: false}, - { data: 'action_see', orderable: false, searchable: false}, { data: 'booking_id', name: 'booking_id' }, { data: 'customer.firstname', name: 'customer.firstname' }, { data: 'customer.name', name: 'customer.name' }, { data: 'email', name: 'email' }, { data: 'subject', name: 'subject' }, { data: 'booking', name: 'booking', searchable: false }, - { data: 'send', name: 'send', searchable: false }, { data: 'date', name: 'date' }, ], "bLengthChange": false, diff --git a/resources/views/mails/booking_fewo.blade.php b/resources/views/mails/booking_fewo.blade.php index 6dc2edc..6add11f 100644 --- a/resources/views/mails/booking_fewo.blade.php +++ b/resources/views/mails/booking_fewo.blade.php @@ -10,14 +10,12 @@   - {{__('BuchnungID')}} {{__('Vorname')}} {{__('Nachname')}} {{__('E-Mail')}} {{__('Betreff')}} {{__('Buchung')}} - {{__('gesendet')}} {{__('Datum')}} @@ -30,17 +28,15 @@ "processing": true, "serverSide": true, "ajax": '{!! route('mail_booking_fewo_datatable') !!}', - "order": [[ 8, "desc" ]], + "order": [[ 7, "desc" ]], "columns": [ { data: 'action_edit', orderable: false, searchable: false}, - { data: 'action_see', orderable: false, searchable: false}, { data: 'booking_id', name: 'booking_id' }, { data: 'customer.first_name', name: 'customer.first_name' }, { data: 'customer.last_name', last_name: 'customer.name' }, { data: 'email', name: 'email' }, { data: 'subject', name: 'subject' }, { data: 'booking', name: 'booking' }, - { data: 'send', name: 'send', searchable: false }, { data: 'date', name: 'date' }, ], "bLengthChange": false, diff --git a/resources/views/mails/lead.blade.php b/resources/views/mails/lead.blade.php index 2126aeb..1c00a9f 100644 --- a/resources/views/mails/lead.blade.php +++ b/resources/views/mails/lead.blade.php @@ -10,13 +10,11 @@   - {{__('AnfrageID')}} {{__('Vorname')}} {{__('Nachname')}} {{__('E-Mail')}} {{__('Betreff')}} - {{__('gesendet')}} {{__('Datum')}} @@ -29,16 +27,14 @@ "processing": true, "serverSide": true, "ajax": '{!! route('mail_lead_datatable') !!}', - "order": [[ 7, "desc" ]], + "order": [[ 6, "desc" ]], "columns": [ { data: 'action_edit', orderable: false, searchable: false}, - { data: 'action_see', orderable: false, searchable: false}, { data: 'lead_id', name: 'lead_id' }, { data: 'customer.firstname', name: 'customer.firstname' }, { data: 'customer.name', name: 'customer.name' }, { data: 'email', name: 'email' }, { data: 'subject', name: 'subject' }, - { data: 'send', name: 'send', searchable: false }, { data: 'date', name: 'date' }, ], "bLengthChange": false, diff --git a/resources/views/request/index.blade.php b/resources/views/request/index.blade.php index 8958c2d..d64a76f 100755 --- a/resources/views/request/index.blade.php +++ b/resources/views/request/index.blade.php @@ -440,6 +440,10 @@ function clearTravelOptionAgenda(){ $('#travel_option_agenda_id').empty().prop('disabled', true); } + + function orderDrawTable($order = 1){ + table.order( [$order, 'desc' ] ).draw(); + } $('#travel_option_search').on('change', function(){ if($(this).val() !== ""){ $('.datepicker-base').removeClass('active'); @@ -452,38 +456,38 @@ $(this).removeClass('active'); } clearTravelOptionAgenda(); - table.draw(); + orderDrawTable(); }); $('#travel_option_country_id').on('change', function(){ clearTravelOptionAgenda(); - table.draw(); + orderDrawTable(); }); $('#travel_option_agenda_id').on('change', function(){ - table.draw(); + orderDrawTable(); }); $('#travel_option_company_id').on('change', function(){ - table.draw(); + orderDrawTable(); }); $('#travel_option_lead_status_id').on('change', function(){ - table.draw(); + orderDrawTable(); }); $('#travel_option_airline_id').on('change', function(){ - table.draw(); + orderDrawTable(); }); $('#sort_sf_guard_user_id').on('change', function(){ - table.draw(); + orderDrawTable(); }); $('#travel_option_paying_out').on('change', function(){ - table.draw(); + orderDrawTable(); }); $('#travel_option_paying_out_status').on('change', function(){ - table.draw(); + orderDrawTable(); }); $('#travel_option_refund').on('change', function(){ - table.draw(); + orderDrawTable(); }); $('#travel_option_xx_tkt').on('change', function(){ - table.draw(); + orderDrawTable(); }); $('.datepicker-base').on('change', function(){ @@ -498,11 +502,10 @@ $('#travel_option_search').removeClass('deactive'); } clearTravelOptionAgenda(); - table.order( [ 5, 'desc' ] ).draw(); }); $('.full_search').on('keyup', function(){ clearTravelOptionAgenda(); - table.order( [ 5, 'desc' ] ).draw(); + orderDrawTable(); }); function loadModalInner(self, data){ diff --git a/resources/views/travel/user/booking/mail/modal-show-mail-inner.blade.php b/resources/views/travel/user/booking/mail/modal-show-mail-inner.blade.php index dac459e..454c026 100644 --- a/resources/views/travel/user/booking/mail/modal-show-mail-inner.blade.php +++ b/resources/views/travel/user/booking/mail/modal-show-mail-inner.blade.php @@ -11,8 +11,12 @@ @if($customer_mail->is_answer) Antwort von:
@else - Gesendet an:
+ @if($customer_mail->send) + Gesendet an:
+ @else + (nicht gesendet) an:
@endif + @endif <{{$customer_mail->email}}> {{$customer_mail->sent_at }} @if($customer_mail->recipient)
TO: {{\App\Services\Util::_implodeLines($customer_mail->recipient, ', ')}}
diff --git a/routes/web.php b/routes/web.php index 62184bf..bb81dc2 100755 --- a/routes/web.php +++ b/routes/web.php @@ -16,26 +16,13 @@ Auth::routes(); Route::get('/logout', function(){ Auth::logout(); + \App\Services\MyGoogle2FA::logout(); return Redirect::to('login'); })->name('logout'); -/* -Route::get('locale/{locale}', function ($locale) { - \Session::put('locale', $locale); - if(Auth::check()){ - $user = Auth::user(); - $user->lang = $locale; - $user->save(); - } - return redirect()->back(); -})->name('locale'); -*/ - -//Route::get('/', 'HomeController@index')->name('/'); - -/*Route::post('/register/data', 'HomeController@register')->name('register_data'); -Route::post('/user/check/mail', 'HomeController@checkMail')->name('user_check_mail'); -*/ +Route::post('/2fa', function () { + return Redirect::to('home'); +})->name('2fa')->middleware('2fa'); Route::get('/register/verify/{confirmationCode?}', 'HomeController@verify')->name('register_verify'); Route::get('/register/active/{confirmationCode?}', 'HomeController@active')->name('register_active'); @@ -51,7 +38,6 @@ Route::get('/imprint', 'HomeController@legalImprint')->name('imprint'); Route::post('/loading/modal', 'HomeController@loadingModal')->name('loading_modal'); - Route::get('/', 'HomeController@index')->name('home'); Route::get('/check/login/{identify}/{token}/{show?}', 'HomeController@checkLogin')->name('check_login'); @@ -60,7 +46,10 @@ Route::get('/user/update_email_confirm/{token}', 'UserUpdateEmailController@acti Route::get('/storage/file/{id}/{disk}/{do?}', 'FileController@show')->name('storage_file'); Route::get('customer_file/show/{model}/{id}/{cd?}', 'CustomerFileController@show')->name('customer_file_show'); -Route::group(['middleware' => ['auth']], function() + + + +Route::group(['middleware' => ['auth', '2fa']], function() { Route::get('storage/{type?}/{class?}/{year?}/{file?}/{do?}', 'FileController@showExpert')->name('storage'); Route::get('/home', 'HomeController@show')->name('home'); @@ -84,10 +73,9 @@ Route::group(['middleware' => ['auth']], function() Route::post('/user/data/accepted/form', 'UserDataController@userDataAcceptedForm')->name('user_data_accepted_form'); }); - }); -Route::group(['middleware' => ['admin']], function() +Route::group(['middleware' => ['admin', '2fa']], function() { Route::post('/modal/load', 'ModalController@load')->name('modal_load'); @@ -346,13 +334,10 @@ Route::group(['middleware' => ['admin']], function() Route::post('/cms/sidebar/detail/{id}', 'CMS\CMSSidebarController@store')->name('cms_sidebar_detail'); Route::get('/cms/sidebar/delete/{id}', 'CMS\CMSSidebarController@delete')->name('cms_sidebar_delete'); }); - - - }); //login pages for worker -Route::group(['middleware' => ['superadmin']], function() { +Route::group(['middleware' => ['superadmin', '2fa']], function() { Route::get('data_table', 'DataTableController@datatable')->name('data_table'); // Route::get('datatables/leads', 'DataTableController@getLeads')->name('datatables-leads'); @@ -476,7 +461,7 @@ Route::group(['middleware' => ['superadmin']], function() { }); //login pages for sysadmin -Route::group(['middleware' => ['sysadmin']], function() { +Route::group(['middleware' => ['sysadmin', '2fa']], function() { Route::get('/sysadmin/tools/content_links', 'SyS\Tools\ContentLinkController@index')->name('sysadmin_tools_content_links'); Route::post('/sysadmin/tools/content_links', 'SyS\Tools\ContentLinkController@store')->name('sysadmin_tools_content_links'); @@ -495,9 +480,7 @@ Route::group(['middleware' => ['sysadmin']], function() { }); - - - +/* use App\Mail\MailResetPassword; Route::get('/send_test_email', function() { try { @@ -506,17 +489,13 @@ Route::get('/send_test_email', function() { Mail::to('kevin.adametz@t-online.de')->send(new MailResetPassword('asdasd', Auth::user())); - /* Mail::raw('Sending clean email', function($message) { - $message->to('kevin.adametz@t-online.de', 'Kevin Adametz'); - $message->subject('test'); - }); - */ } catch (\Exception $e) { var_dump($e->getMessage()); $fail = Mail::failures(); dd($fail); } }); +*/ diff --git a/storage/app/google2fasecret.key b/storage/app/google2fasecret.key new file mode 100644 index 0000000..1f6c1a2 --- /dev/null +++ b/storage/app/google2fasecret.key @@ -0,0 +1 @@ +QPQFA625AU3D3CNFX6KX7Q5XISEDANIH \ No newline at end of file diff --git a/storage/app/public/pdf/passolution/Einreisebestimmungen_de_de-MA.pdf b/storage/app/public/pdf/passolution/Einreisebestimmungen_de_de-MA.pdf new file mode 100644 index 0000000000000000000000000000000000000000..957f993e7d90b9be64e64ab02f0a1eaa69d309d6 GIT binary patch literal 48561 zcmeIb2UJu^x3G0jGDL+PijDb)S8zp0kTiSzMA8#KwsZ0ssLHCf4Zu z`~Y@!Pe&MlUCh|k*w(=Uon6Vz)z-=$<^te=pQDP-u54@pf5Cb70w5@e4zo8qD|q(i z&kFvd9J`o$h0|5GNl3j)q!13b{4B+@)19lk*fb+*87l0G`UAGJr0RC~v z4FLaUQHBQq`EdvW0wDh~FLB3JO3l^S752T7QflxT0Kcn}QiE6FtYhGfE~Ul^0R7eh zQfgoT=zH719XRtr0cK`pEb4Fvpa*0F0^!Ba|3Y{mY#iJ`05=%K#?1pXK>u9_oH=>c z0ebB45diOU*d12@yNn&YYsCNtKl=2{=kL9A-mGSBrZ8s!!|68!GXw_&I|N7ge{%!? z0zU#50u+H8fdj!9!2~WbMG%Bbnc=@;2+9cJ2$GEO&T@tsyIMKei=TPQAkNDHm>bB&4CJ5(0_oxBDL9z@XQ!xJx!S^Yz^kE#ppGDcpo*XfH>HlCgrEUGR%1MC zk>3X8S@--p%>H(J!H2pt3_g6mw>7(ny}g4gd~^ap=N$|Ho%bSuF_O9^r zT>#$)z`yEo_WDOXB&}>+;myb{X$x-(ahR!t84R6W9%gUhY6(}&!+F+8F0SzAvO~X< zT&&&eJk^0Wy~ga7s7@-@K&4ApLC_hp@e0qBJ%&ZtSy~YZlfXzg{wuZ4d!b&*_fc`g z2Vmj*vHW{u3bpFUIEeBGD-$b}DV}X^2E0w993(>0{7bt&%7&aBInm3h<4NISV-U6TamE>AHCWcZLlVK#U5g!jP zB_QSw;wNsY$f(R?04TIV?O|VTDSFcJdk?d>SYE@_25cIaj)m#GpF^kjuDiw{h10eT zLNfGZ^6wl>yR|YBr$&A3aoxu(75Px@ooB3ID!u9i`A8@E$kJ06i)UscrJw5R8jCGO z9h|e6Qiyxrk=Ml*i=-0N8iwmQ<4`>7vKqL7jM{cDHlY*E3Lil!_tfydNBFv@2I4Ep zF*_IgDU$3qC0la#xNH%={0`->1EDU4Z?bC=uNAMNdOV-(noPIGY(>UvKU_`S$_8&# zs}4ohMi&-ns-{u-j=Xq&tc{%(-;;jb2AL|>wU}(I+aL;AIX2*C1SdxN!}YMviit5V z0+wt0&@Uzi#NdC07HHG(3%sx>|^P!8o zod!Gj)rjhx&Ip#^YSdr_Q@ZPwhSJz3ffv>hG_)@i)+V3SFM4ylwSQrP=%Nrpn>fG> zD(wjw#aCM**Ws3BFYIoZ%nSGk>-R11PN?`Y`=sZsLq)+O{y9CY(~VxHZyPpxypn=1 zg7?H#u}enwGUL4toNld+35ZHZtcFm+bg9cGHQ9}cg1ah1+?O@#!Fsis&6cgTl^@KO z2jinY7`r3LE zg13jX;P1rHrWR;~fmyzR&N-@KqSkIzq|&cDzSi*Miq8mIjOGlQkL~AEB@rKg^MZ^9 zgWCtNNf?`~-sKA zA$b$B9x`W9B3&%$eVf$PYs?78pVh~=%&g9G$!1>o<@Djq-q-u_Dx95VO>AOwoy@0S z2%i?L4{i;Tjj0;@=DjUX`O<;T7!p7wMI(t-$vPu&%%uS2aN zI|lEQYIcw&9yoC`uuDDl4tyqg^NRe(B2rX;h+;k&y+`P~a^p~e=sR5U7y&w@NRc;J zUpW+DOJ@=7epzAr)*_^B9ci@qPQ$Kmz{7HvA#0Ph$>Yt)jogqiM&k#b<0!L(woOIE zl;q}!gkKn7u_^b!f_@QK?rqr;OZIw+rww*F=;7nrNAyLJBsUUI43>)D)lbG8*T2i4&t6DT5nHBMUa^Ris$U zj#qZ~eSLj58sg0(mWMNom)7FeQTtdI1G5D?i3P~z@2L=1Dx!lQdo|{FVoUO0pW~Y zCb&k7tpeyKPZPkND1yd=_OQWnZ)Rru!(~xj{(Sv?p_Z{`A1vUHV=!KL?e?0>d>& ztTx*(k-^01PzhvK13LdjpIT9o| z-9%ZX{H7$0wMlHc==uT;N$<-T>C7QZ`B!8tdHm!k65&`OWTqk!ji?ZGh6i1+_x-8W zOYh`BUlE(0ed=zkudJ+h@%3`5C=r;8sA;e2 zmR#Y!ZbT)O=+mQDj4rhqKN_`e>`n4z1Nr?&qm!#fduI2kC=d$x5?;6yhO%@b?u7&# zlxTxl9GBy<>|8`VhOn<{UU?%K|H7Ft*s&4=?V)U9A8RU#7PZe|ly0;Rj#1f*+Eql& zq`}&xxEGHI{fi_MAL@9aY9A-PO~v2lXN!FvIq)E5$!L=<#eNKlX{fKf!EL^)U&usp z{ehL(lom|GLQ7438Y%L0(Oq_fm0r-bh^3slmxWj-7T;CR0?~k~wu*LcB;;GfYe$X` zlQb_fsgj5k{X9wIjp}QfGM~w`7chxoC7-&jC#2m;l*2?dycdB^G3LyH7S<`Hf?;a$ z=(?8_Wociv_syZ{{Mcw&d6i_e8J+vegdfM7R=k|FZ-+p&Qu*ZKT?lzJ_t?K!VsS^! zIdatt$p}h*=q7Xap(c&9zr*>!73l!qSN)Y?l;!}PO3|R@X}3_&|%%Xryj%cecM=tu++NlrjLwk>D@zKRX1Fedh4$%S1oK8S}zWbKR|m< z=B@iAFCOeOLW$P(X5?9IT$dGEsWC@y&5+;X%5#Yv6e;sc zJo!S9C3nAI(}{(=Bzd5Hs~M5BQnIj&Pd*n=kP>FZc*UkHRiM21^rU-0{UeF*V#{t* zue#8^IYyhpkcKU%^sitfq^0F0f7`48wb45B&$e0Ek{RDteU7EpbCGXPrn&VlPl=XJ zcu?$MAV0yH3N9b`Y%_;Xc01Tbc1p8~zGy*jvon+E?oe{!!CQUoqJejx?Iy(J2iaCC6u6p+KLEL6W_H6V} z8^=4kpd{Lu0I;Sb<$ZH(&Tis#KXjBBq(h$TeDaSwe6Z;i2$@OY_ba~lebpH=%pNKv zNbHLj(V{H~>v|g+tj-?CDx=y4VdOsJ5A~TrJ4|HkZxb5}+auPX?aBTag0oxZBRnaw zZv-n-HdIWZDkiM!H8{lKNL8y}%3&|O`|cKBB-xdKJx7>`3X=M2(w7Jv_E#~ylFAxA znSxovh_RZ^xO!zTjP6GT!hCJ6M;%?|O2O;piY&jyg0Lrh6h|56)P2Xqg+8DbkXZ)?DAxDocC%G{*A_PU{jF z-qb-rC0suWAVsGRi&d#N_90~G*-<-u8i-zPYM1`bB4{`Ze+S=V4;a9+iF0zz!3;C5 zg+C`Henj#?Xnw6&pll?$y9y1yvd&i&RnzjrcmhfWhU*0e#PA!N3K`c;yQ>9{e6EaV z+NNhlLD=G(`)*$^@YGHMM1FfV{Bp(1;y%$E@0j;7+^QmU*eYb|m?zWd>f_7H`0~QY zgI-HJ$bOG}D#IX5NWFv8Mw=CQY2bYJWKdMVHDn~%jG)(msu$gw0b!I7!BGT~& zdzjnvNERpz1#{_^R3ORRAJb^;fudB*mL*iqxwU~0;Z zy)sQA;*gnaKJ^lbmzJV^eLPzUe~-XZtacA)9*oVH4o=T+`4x?n{+>>uvCW z`(y-7UwVxI&b^3Ca#Lu*yvc5@2sl3_KB)BP6o$Oigc5>Ux93?XHY25 zQsGL!U)+e8t_Jg!0&SYSH(cJ;^2)H9x;igRd9xbVgn*)I*^#tG`K}Y}kh@K|LS|0N zjM)!lbLS7fS`3CE;0|kG5yqI-Z!dH@%So=zwZEM5{W4G^Qp~ed;Xn!t z!zlFVh2bY1iJRZrkzgZ*1T-7tJU4m}G?0d~YwtY?w5AhELyEhuMBKae-BQ=QR~27{x+bA$Ta z`bvtFTc1hV3m`Xt#nKE64KaH{TJKh9ej64at||&xbWKS~4t;;cf<%C6F}`PWT*o%u z3_!Tc&t|nB}%u57*U|q1EK%D%s zwL+9moV>$a;^RDtNI+6SO~2n;|C$!kxT_j{%K5aY7&2s)s_7;Q39NVW^xL>{w+sdD zg|4VKi9?A?1zhX5XS<-X_pNczPhVqTs&T{o3bZS)l9&LV24&9Q@dHiwpvQ@FsOwgK zfUBVTr2KX^sKi5(kt>dH14(l;CGZY$Gh(%xt#r0kR|q4gdV3OK3vF(@31lP<#Mkrr zo}>Qw6GBu%TT}O<9gQo^kB`+CtY0B1-%SISjb{6;vc@)aU>Mmy^6m-k)}EhG!Y&BX zj?G|dEqeVH)^lC^3#fC{Kuu^_=)SC}CckbnoN0Q#<9-gjR?iWr0(uepGNw@ zL$2O5eM>B|VNnQ)M6F{Z%{UYt=599`ho4)1qDqseZcdmTYM~QqfxAwv#(k>;<8?M5p4CLUvMvVxR2nh+E6i?kKuV@5Ry_A6%Gq)jVbdi z*u&nhbP<_S#px8&ztY3?U>_7714juOV7^^;Nqd4mh4pF>TD^Vk1WVU@MjM&19&M>o zlH~pEzV8K;LHuHI^qsaM%ys3qZ>ZKCNKnM~Wew#^0Uq&(>?jo~Zun{vPY z0%NbGU#20H1t0J}GO?J*?$K8=?C3DQ6jzI<*>w~+`*d#4OZ2=ZC-w<+JV%h!zsg}y z)k9?j9zw&JDu>JQxu~q(0w{U<{6i6MabWHiz(N?lJ{k->Ex~xjAqN)1V;=wVR3w#| zi18_MMQdDT0g{U~V=%H;YFq94^_n5C`CB7mW2(23 zlbYBg?lE7@m#k!T{mVU z%0q#YBUBPEqiC-w`04Z-y;hp_#RT+_&VIi4K~;^<=036_4us*k%O+5;$Kr}T&b={m|q9hljV83t7;Q2-Zw_3wO5@oYKiFD4s6Jls4#O*SM2xvxrN21*1e z<9UHdwCh$f=vtb-*%X6OYzMly7?JvQPF;t3oKD zEZ~$#_6Sov4p|fucsw5-3QUm}z$;jh7|to3Z`+ild#PFb2=vgt8myE{^ikhewF^^p zZh=pNP}?tO)Ph_?b=1W77JnH-)xE$T^NB*{gy++F1y4yY85m7j#)sz&IQt$JHQMGq784A%Ff{NIjklER_ z(sz~iBw#`93)=T&?*ZLQ_EgbWzM8)+5egC`>D&8Q@GcAY$&4cUP9#o+wW)se?1pF$ zM%-$4<@L1(g&zxe_|jaitR)C2mAETDCpYI;)8Q$>!T0vP&X*N9lT)VakjbNu=v19q zW8M73x|ul+)|uSrEO;kFl{udn@P0w=>F_ngcs31(np@K<)GQ`+ZRi$-OaU4!r+%D# z6vf{}e?W13ZVO5MrJHX`D{e5W$koP~=eE+%B&&LmxAB7#{Y z#vps4>m|*8wv_8LQmvvyNNZMm5SDJ z>uC^G=rec_v${-`uIge3am(lkziKlI&}3}2CT2kTD2<^}YVjd}WF);bOGu)<(!}^{ zdYwu8j%dzWC(WsDaou#*43PI#=wczkqt-pmBpjBEbj;NOWuAQbx1+Zu+Ow~@X}yif zUoR+xGL)Iu*mV|Lx{dVMRZY|4h#_BnoKoF4O);ik@^Wh4*au@wy~$A`;Axt=r0!KB z6rvOq<}oL*!PFwe?wQqBZ`K5RyZx|c;T)sdM{&>s#;_i%)xBr24lmw>r$24{+7K(S z+Tr-dDmVaG^(InpMZdVZc+9$%VeRc!rs@r?^6h*>N{04l6||+=>Ia=ZD@Jy|=Pg^GHYcyZ z!Bgo%(Y7+gXZ8<6ZN$5GudXeA&{EdPExJkq?#d@r$a0LbD_E0lmhpoHvueg0NyPZ5 ztG+g07>-c!V_|2S@H8^$LY`LP34O!5Xsw5*IE}okY_#o2)3;A$IAb#thYLy3X*r=#yF65sGT|qn zDSktHTkf{@9AG^>JkT?Jk!*g_LN!+2L*39AIW*$7$U+N^&I|HuhN;gfP>`6phN@Q- zAcTnt?L0x0_2iXri~NMFAM%sZ%`vI>s}`{iM2td}W!y+yG|>f`5wFp;Ws5HZ^DNN) zrnv-4hOgVW*^+$tx@>6{ymT*%J^g8&*L*~e?n7>MO4h?H)kde`ZE*?oA+@;$XGTg4 zDnX7`l5*W-_be2F-Iq>puEg4R;%cu z?i{nEn)u+ccwsC?h8`Tt<>fk~p)z@ZoAPo?@@$DI^F;UPOpo@^*IpF>hn$N~Cg0U0 z6}{2}62=`VXnHGqb&ooWxs{a0H@X{_>$%#finbSXj)$rE6Lx@tU5-5KdMMqz)&<2i zXN7YncOJadcjBqmwRK~@UAs`SPNCXc3+Z-OX|QJ}3Uk=2Gbk%SHPvOU!!@qrUG2Cg zuQ`*qzS&!=Rf~>^VF9aNV7>C0eR}RqA^|h z2Uh0dy0O`5SK4g>M~9Z_7|za4)Mpww#0X1~d7;6pClCrUvj>m8O9E)hWb(*R?C{oK z4z%BPw2Im3>bw5_Sw4mP%wn^D4~=>pwN*4;5wOS+3B?gx4_Q8PS^9h_QI`V|r z>Xh1>`5ywtNj2Uj7dbW~aO(_tU>)r5IH@0ZW`DjV2`KU7)gEhHzKktKuy0Y#Seia@!$twR>e#&E+2>HRnpJUbb z2zSVnm5~uY+^eUC7x~~Xg1mKyh2olev4HSM^YAw4vJC*6@!AX66MXvlFFMsNc>O1Sw3E~)BYViu2 zdiLb#VOb)XIQ=`44JN6$Ih}^4W0F?e-Fa7gAQq?=Egl2(3n?+B*UVNwPx8&Jx`07- z%Qq;m1jv-&e^Vm$2=3xp=JqMTp?-zU8)Nh451jiw6Z3ry=$x)D zlZ~5`8;+9waE+6L4a^ON{^Z)Z$_v*2$Td4-_!^o6@3~jPKl%21U(VsC3)=q7m*4QT zzxIV2$_9nPn;*o%2Ib)3{+BNta10R&kLZ8jO&q^2P5xmwxx#FDft)}n5Xb`t0f9d` z@arPw8EW`nX29T8KLa2+&pQyndG7mJ(Ec9`7{_;x@Lyx@T=1hQ|LWt+0fZ0V-+!Kq zwdI_rq~R18L9MM+u*9*5B_xKm*Imy}@538h`-7{r7=Wk3eg??FBfJqxkg2zpoWz5& zVV-E)^d3W+Qu5rQw7q$+6Pgnext;yf?#u@d9_&nD;|+fux{Y1R=16jfy0|L?y2m`^ z@P&iVIp8Dr^KZlxh)VvcV$t-+U0H)}{=_u|cT-8eQd`N8`tMX8-E-Qqm0v4#S`Pz; zTk&Vj$tCCq=Q>I5ttnaAEN`Sdm1&eFPn@WWa+NH2(obH;OrFokiiJ#5XRphj)72%4 z=A|MnhW~c?W-r-?PXiT}@x{8^>wI$Lm9OTVkwnHJn+Sa#Lw2oLxj~%v(T$z~cgQJAK?;*&1m&BOP8q1_YHpm~jP0ZY0duD(? zc3T@%!3u(ihXMGDgXUZo+W~bBp%j76!nf@oRc6Zd*|cmlU~;T0_U_M@p_0(BmyHM{Z%#%iO0R` z#w9Plnn>W+-*mUN>^B?Ad6lpG9KC9M#b0^y(?F(XL`g5+s=?wp_PG! z6|sbrAH`!<-=Ncl2iUm1mKA-?W#ubb#lrh}alrcRDB+Sy_3EkKAZblTKZj$>rsU`Q z!yEi2V_^ebs}HbQ3)CSVT}^vJH!|{?c%eKlG@rBW9Ve%*f1cPzp|W)=-K^;`SDzI- z=zLzJFhl^=1kOlv8ynHR4mX#6uvAr|;iYCds>nvZ7#}eZ35_SCrPZrvP3&boWgS)< z8%oA{h%xMLOTq?N+c&<-A*W%VUW;+!54sOzQ>%=!R-oc?M}HhGUDVOYq)sf{LkTWo zDu9i5%}nIcTkXH}Gf9|KPGPbLGW4E|wXKeBL(j)oi`LIv#TiF@8 z%Ls8BzIge5p{N6&OW4qV+yZg$!0zS3{C&GLv+f&FA2S9qj?`rc$+Je;j^q?$n>#y1 z@Umn)QQy2NTKSSI+^WgYu=1Q}q>fA$V(aQf(<_ou;l*9-5K8LN{y9U2Q|FY&a<%m^ zM&t7}msnG^lZ9`E$Gx0-Ae5nNK3%z|_^22<{wT+_QLtiiy>4XRn^&2SPdu;4ceAcM zO1egj8>x06KY;ZN>H3UwCC7;oeRPe1u`!2vYQ1(7Gw`RYgXN>pCA7 z!QI9El!wz(Ycq;0M~RK(TrAed(P0lN^GOHU-Au`5g;tJ(hA<@ta;8@TF_?A@yk1xW zscm*C2CBLvZ>rB-`RZY#lP>?7(f~tSws-;UBy~6;Ej90RFK5yWj-2GO_U9(iFxI~9 z93-p!k_uw%C(`NF(GqVTi?Gd^%TsX;`G)gWhBaN~%VGVLLMo_K`R(bmo;`1ZNP|V4 zf;5&6Qscvlu+}G#l=p7t_Oz}7C-R%bu@ZR+NNw!}7WiIo$J~}lr3>Ua&h7jp;-}X z#?*MW{F8TcTSH+l_<|$?lJ2ze8Ew)a@@kTnk@8Een{=VsJSOkFdENHz$^D1@2y*@{ zdz?pY?9u@iHHE z?D-^f<1}Rs7)N1|7hK+c_vR}k;kC->~b87Xv)}yS%oZ`{jO93C|yQpMSuhhL@ z)9brOQA>>?_@4SSNTVJ5=I&$ZFWjL!q=&c)%w$d1mnD4mT6evcS3g+tZKJVY&uc4N z58OMm|%qWz8FqdHShFy7oG^2Enag|{t_H`BBxTvZed1$J-W zBYZ42ZwGCj9{bd@9hM-8vCBG9cf#;>4Kfi@PMIuYKorT*{PC8DD-NT5Hb1Vb&9Tmu z!mXo&lUJ=X1XK;*WE9EL0Wwxce1n*Enz6!)yuWFKm9=|NIsVVd-p;Vg~ zdCz3;cE|v@cf&f!bR5p}`h3AMxj!4;CIy;=9(p?_5-s4bKSGSI*=*JJ;QID4df_gI zounPoO_`6D19_iYJt9I)q7i0&Q8vgS@i})M$j~SotlxMohC0SQt7VAvzW&iC#JgO> z`nVa(?)yd9Z&HP>>k@c{Y)j_#NsHIZm_Mhx85v06OVtwe?aE}$lZ0Qx=kw$HP+cNamk8A*LUoByT_RMM2-PJ*b%{{@{}7=% zPiF96nn(DKQ2oe{@c(dD;m;8&j_=RsUm{eO2-PJ*b%{`2B2 za{>Avh)|s)C_kM0YlMp9d%`L9zh-m(5khsY@`Ck0;*9<+gz6ltxuE<{up`djGGzU= zYySwLI#+qY`X9OW_YkUcHt2%3KlA0cOjCdD%RfS>IDh4z{wYFro`CIV2mV_SDmasO zhERdO=g$J4`~DL`#rZwy+P@I0bHR_A{Nb&}4k;ago!inE<=279)^c~XdzBr8ro!jEyj3rMTJEI zM=sP`scZ0=xNI~Eu3PA$W5@expMdG^*zsH$ykG`dOWnaCj5P0>+?C|z5%#UAk|xqc zjeOoZ%BEK^M~$23oz$eE3d;nsELWvIqt^#d`t?!{R*$AJOTuJ_ zc7UDF!WuReqOl8(n(|x)Ntm`)o0z)uWHBbX{pgPw+>?)UhXYpYo+%$i2MZ)@e2d^! zG>zs~NmKVJWoXvllN~{#C-6+b{v_5wE>=o3>w^6x)4|Rl=~R-~o6Gwa3nt%YgRx`nkRgH@AXvr5`jQgAlHoZ&PXY+?S{nRefRR@*2eo z*3!k7qDfX`7vl!YQ(n9#XkZmmA#c`?bIVSPDO=KSvcPPBjO9~#jsA>v@g8+??07o% z)jS&n_0fp57v9N~yis=1569Kg*IMpr(BxGtuJ0>~ThWSIm}?d=zY`Z%2@k}nL(gig zQ;pI~Jur6<3g#sy$DI)vfPEvfvbD?87x;>hvDFaL1E^UJ4T3X9bv zvEoM}nS?cfI|hro^)VzZp${! zKfPv8w~O|@OcZ{J-7`gT>W)fI9u~=K3GH7E-I(ox)9G?yNCc5LVXqq>%ijsTxpGr& zK##%C$4TkI3*yhpS2;eAVsuEDMA7AmB{ZwNE6}^n4;|0y=*OCOO$PF)20Dm@$EEOL zN4}Dp@PPGchF`l{L%HbjW%VJbvh}g7dIrXTCeZ^!tNzidf+c8t;TX46htttZ@OH2c zaaQr57uek|1b;LW<8=U&h5%*sfIdI+6>O&WR-vzrQD>Vr&BS+;opqW}SHsGuv`ou1 zYg3q*?VnUPJhJJ^|1dZiXMly7lCP8Fl@yANQ`SxVhPdPEbbPL`(*~ALqNw>0zEM#l zMpNgslD+|O~YMgLVHdO!aP8z#d?v zRa?lgT)^JMCf!%RC~|5|l$S)CNgd<&U%pXNjg}^^?sJ??#^uNAb2q2jm5qCurI4@? z2^JrIJWaw`)3q~KBTN%aS=_ScKBZII&|suTR||mWn)|q3?&G?Va`%W(7(u?hI6Ghc z#niERHS6S!4YCHKtQq@5#HaXMx8j(_1s0CS_nQ{-D2a1{_~lz|W=k)hSZwOL&`wIk zunR=~X^+#P~C z13iCvQR^}iS%k@%JP(IEF%Iwa!tZ@tdHm6@LG*c~G;K!n5XI9$b7*R+;jzew(6_oL zgF2jdYZF3;2#T5Fr _MU?P*EYnJXMqn(XxQ&sF5X28=4st4-A8(4O_-4;7`o>_ zMUL%Cxksgi}duypCv+?@=`|ByV0lZJA z%FC>Yy_(JLojwcLNc5AgG*YPQOpbtBKjlB=6uss=Y#Es~ovxIYvZQf>??kV?=lxBk z#O`(TmPFIX5yH_9YVoJ9_(X~w_(=&$Q4wki)2GvO3y6epRYTcQyQJKfGsx0#4?O2* z4jQOlRqiZ?!Sh~G4IH9$e)>EVe3Rd>m!OI??2B(%_EajK5!$0vl;E>k95 zrcCC?G5x(<2KXyL(!%6u6J5Le)Iqw61>i=vZ;ga{cq0?{lv5g7rUg?eFnE=OD`kZGYy=_Z&h036}Mbcpvb;_E!0^ljA?-ea?4U z{Mmv37TyQ)Jy#Osd#)tNx$i&mKH&4zr@u?nbuRc(lRv!G_`&;d!}sL-J@0e2aUMC8 z2)=RNCPxY0oUc#?S$7PTldTf%t%5{u3}vLZ4DMN^2&^5)WcOYlOK}~dls@kgfwl)B z@}@E+6iDN)-*wuobx1{GVWUCUChNQt@i=Dhcz!ELi{0^wIAbwGI@PjP=KJk|Jz6sn zoWWD(SC4~pRD^Y2ePGE1V`|6x$4cQce~5jaP8wTlad4a3LoheOGPRRM!G%m|W#v

=x*Ng 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 literal 0 HcmV?d00001