From 9b840a24dd1c9b999fd090f1ab9d26d08c78642e Mon Sep 17 00:00:00 2001 From: Hillel Coren Date: Sun, 1 Nov 2015 20:21:11 +0200 Subject: [PATCH] Enabled social login --- .env.example | 5 ++- app/Http/Controllers/AccountController.php | 8 +++- .../Controllers/AccountGatewayController.php | 17 ++++---- app/Http/routes.php | 4 +- app/Libraries/Utils.php | 32 +++++++++++++++ app/Models/Account.php | 10 +---- app/Models/AccountGateway.php | 20 +++++++-- app/Ninja/Repositories/AccountRepository.php | 2 +- app/Ninja/Repositories/ReferralRepository.php | 31 ++++++++++++++ app/Services/AuthService.php | 10 ++++- app/Services/PaymentService.php | 2 +- .../2015_11_01_080417_encrypt_tokens.php | 41 +++++++++++++++++++ resources/lang/en/texts.php | 2 + .../views/accounts/user_details.blade.php | 12 ++++-- resources/views/auth/login.blade.php | 12 +++--- resources/views/header.blade.php | 30 +++++++++----- resources/views/master.blade.php | 4 ++ resources/views/payments/payment.blade.php | 1 + tests/functional/SettingsCest.php | 6 ++- 19 files changed, 197 insertions(+), 52 deletions(-) create mode 100644 app/Ninja/Repositories/ReferralRepository.php create mode 100644 database/migrations/2015_11_01_080417_encrypt_tokens.php diff --git a/.env.example b/.env.example index 4ca1bb2d34..c955b9de3a 100644 --- a/.env.example +++ b/.env.example @@ -21,5 +21,8 @@ MAIL_FROM_NAME MAIL_PASSWORD PHANTOMJS_CLOUD_KEY='a-demo-key-with-low-quota-per-ip-address' +LOG=single -LOG=single \ No newline at end of file +GOOGLE_CLIENT_ID +GOOGLE_CLIENT_SECRET +GOOGLE_OAUTH_REDIRECT=http://ninja.dev/auth/google \ No newline at end of file diff --git a/app/Http/Controllers/AccountController.php b/app/Http/Controllers/AccountController.php index f0f55f12c8..2b6fc33216 100644 --- a/app/Http/Controllers/AccountController.php +++ b/app/Http/Controllers/AccountController.php @@ -38,6 +38,7 @@ use App\Models\Industry; use App\Models\InvoiceDesign; use App\Models\TaxRate; use App\Ninja\Repositories\AccountRepository; +use App\Ninja\Repositories\ReferralRepository; use App\Ninja\Mailers\UserMailer; use App\Ninja\Mailers\ContactMailer; use App\Events\UserSignedUp; @@ -52,14 +53,16 @@ class AccountController extends BaseController protected $accountRepo; protected $userMailer; protected $contactMailer; + protected $referralRepository; - public function __construct(AccountRepository $accountRepo, UserMailer $userMailer, ContactMailer $contactMailer) + public function __construct(AccountRepository $accountRepo, UserMailer $userMailer, ContactMailer $contactMailer, ReferralRepository $referralRepository) { parent::__construct(); $this->accountRepo = $accountRepo; $this->userMailer = $userMailer; $this->contactMailer = $contactMailer; + $this->referralRepository = $referralRepository; } public function demo() @@ -223,13 +226,14 @@ class AccountController extends BaseController foreach (AuthService::$providers as $provider) { $oauthLoginUrls[] = ['label' => $provider, 'url' => '/auth/' . strtolower($provider)]; } - + $data = [ 'account' => Account::with('users')->findOrFail(Auth::user()->account_id), 'title' => trans('texts.user_details'), 'user' => Auth::user(), 'oauthProviderName' => AuthService::getProviderName(Auth::user()->oauth_provider_id), 'oauthLoginUrls' => $oauthLoginUrls, + 'referralCounts' => $this->referralRepository->getCounts(Auth::user()->id), ]; return View::make('accounts.user_details', $data); diff --git a/app/Http/Controllers/AccountGatewayController.php b/app/Http/Controllers/AccountGatewayController.php index e448f5bdb5..9f190bbf26 100644 --- a/app/Http/Controllers/AccountGatewayController.php +++ b/app/Http/Controllers/AccountGatewayController.php @@ -60,20 +60,17 @@ class AccountGatewayController extends BaseController public function edit($publicId) { $accountGateway = AccountGateway::scope($publicId)->firstOrFail(); - $config = $accountGateway->config; - $selectedCards = $accountGateway->accepted_credit_cards; - - $configFields = json_decode($config); - - foreach ($configFields as $configField => $value) { - $configFields->$configField = str_repeat('*', strlen($value)); + $config = $accountGateway->getConfig(); + + foreach ($config as $field => $value) { + $config->$field = str_repeat('*', strlen($value)); } $data = self::getViewModel($accountGateway); $data['url'] = 'gateways/'.$publicId; $data['method'] = 'PUT'; $data['title'] = trans('texts.edit_gateway') . ' - ' . $accountGateway->gateway->name; - $data['config'] = $configFields; + $data['config'] = $config; $data['hiddenFields'] = Gateway::$hiddenFields; $data['paymentTypeId'] = $accountGateway->getPaymentType(); $data['selectGateways'] = Gateway::where('id', '=', $accountGateway->gateway_id)->get(); @@ -237,7 +234,7 @@ class AccountGatewayController extends BaseController if ($accountGatewayPublicId) { $accountGateway = AccountGateway::scope($accountGatewayPublicId)->firstOrFail(); - $oldConfig = json_decode($accountGateway->config); + $oldConfig = $accountGateway->getConfig(); } else { $accountGateway = AccountGateway::createNew(); $accountGateway->gateway_id = $gatewayId; @@ -267,7 +264,7 @@ class AccountGatewayController extends BaseController $accountGateway->accepted_credit_cards = $cardCount; $accountGateway->show_address = Input::get('show_address') ? true : false; $accountGateway->update_address = Input::get('update_address') ? true : false; - $accountGateway->config = json_encode($config); + $accountGateway->setConfig($config); if ($accountGatewayPublicId) { $accountGateway->save(); diff --git a/app/Http/routes.php b/app/Http/routes.php index 0f2c082431..999b640008 100644 --- a/app/Http/routes.php +++ b/app/Http/routes.php @@ -404,7 +404,7 @@ if (!defined('CONTACT_EMAIL')) { define('NINJA_GATEWAY_CONFIG', 'NINJA_GATEWAY_CONFIG'); define('NINJA_WEB_URL', 'https://www.invoiceninja.com'); define('NINJA_APP_URL', 'https://app.invoiceninja.com'); - define('NINJA_VERSION', '2.4.3'); + define('NINJA_VERSION', '2.4.4'); define('NINJA_DATE', '2000-01-01'); define('NINJA_FROM_EMAIL', 'maildelivery@invoiceninja.com'); @@ -415,7 +415,7 @@ if (!defined('CONTACT_EMAIL')) { define('PHANTOMJS_CLOUD', 'http://api.phantomjscloud.com/single/browser/v1/'); define('PHP_DATE_FORMATS', 'http://php.net/manual/en/function.date.php'); define('GITTER_ROOM', 'hillelcoren/invoice-ninja'); - define('REFERRAL_PROGRAM_URL', false); + define('REFERRAL_PROGRAM_URL', 'https://www.invoiceninja.com/affiliates/'); define('COUNT_FREE_DESIGNS', 4); define('COUNT_FREE_DESIGNS_SELF_HOST', 5); // include the custom design diff --git a/app/Libraries/Utils.php b/app/Libraries/Utils.php index be06b70041..8b0a148c57 100644 --- a/app/Libraries/Utils.php +++ b/app/Libraries/Utils.php @@ -65,6 +65,25 @@ class Utils return isset($_ENV['NINJA_DEV']) && $_ENV['NINJA_DEV'] == 'true'; } + public static function isOAuthEnabled() + { + $providers = [ + SOCIAL_GOOGLE, + SOCIAL_FACEBOOK, + SOCIAL_GITHUB, + SOCIAL_LINKEDIN + ]; + + foreach ($providers as $provider) { + $key = strtoupper($provider) . '_CLIENT_ID'; + if (isset($_ENV[$key]) && $_ENV[$key]) { + return true; + } + } + + return false; + } + public static function allowNewAccounts() { return Utils::isNinja() || Auth::check(); @@ -804,4 +823,17 @@ class Utils return $entity1; } + + public static function withinPastYear($date) + { + if (!$date || $date == '0000-00-00') { + return false; + } + + $today = new DateTime('now'); + $datePaid = DateTime::createFromFormat('Y-m-d', $date); + $interval = $today->diff($date); + + return $interval->y == 0; + } } diff --git a/app/Models/Account.php b/app/Models/Account.php index c1637700aa..fe16924f68 100644 --- a/app/Models/Account.php +++ b/app/Models/Account.php @@ -490,17 +490,11 @@ class Account extends Eloquent $datePaid = $this->pro_plan_paid; - if (!$datePaid || $datePaid == '0000-00-00') { - return false; - } elseif ($datePaid == NINJA_DATE) { + if ($datePaid == NINJA_DATE) { return true; } - $today = new DateTime('now'); - $datePaid = DateTime::createFromFormat('Y-m-d', $datePaid); - $interval = $today->diff($datePaid); - - return $interval->y == 0; + return Utils::withinPastYear($datePaid); } public function isWhiteLabel() diff --git a/app/Models/AccountGateway.php b/app/Models/AccountGateway.php index 16d72076c3..fe1afbc693 100644 --- a/app/Models/AccountGateway.php +++ b/app/Models/AccountGateway.php @@ -1,5 +1,6 @@ gateway_id); } - public function isPaymentType($type) { + public function isPaymentType($type) + { return $this->getPaymentType() == $type; } - public function isGateway($gatewayId) { + public function isGateway($gatewayId) + { return $this->gateway_id == $gatewayId; } + + public function setConfig($config) + { + $this->config = Crypt::encrypt(json_encode($config)); + } + + public function getConfig() + { + return json_decode(Crypt::decrypt($this->config)); + } } diff --git a/app/Ninja/Repositories/AccountRepository.php b/app/Ninja/Repositories/AccountRepository.php index 0cc11aa6c0..a10ac45a9c 100644 --- a/app/Ninja/Repositories/AccountRepository.php +++ b/app/Ninja/Repositories/AccountRepository.php @@ -198,7 +198,7 @@ class AccountRepository $accountGateway->user_id = $user->id; $accountGateway->gateway_id = NINJA_GATEWAY_ID; $accountGateway->public_id = 1; - $accountGateway->config = env(NINJA_GATEWAY_CONFIG); + $accountGateway->setConfig(json_decode(env(NINJA_GATEWAY_CONFIG))); $account->account_gateways()->save($accountGateway); } diff --git a/app/Ninja/Repositories/ReferralRepository.php b/app/Ninja/Repositories/ReferralRepository.php new file mode 100644 index 0000000000..c847f3386b --- /dev/null +++ b/app/Ninja/Repositories/ReferralRepository.php @@ -0,0 +1,31 @@ +where('referral_user_id', $userId) + ->get(['id', 'pro_plan_paid']); + + $counts = [ + 'free' => 0, + 'pro' => 0 + ]; + + foreach ($accounts as $account) { + $counts['free']++; + if (Utils::withinPastYear($account->pro_plan_paid)) { + $counts['pro']++; + } + } + + return $counts; + } + + + +} \ No newline at end of file diff --git a/app/Services/AuthService.php b/app/Services/AuthService.php index 0d6642d261..f5fbc0c532 100644 --- a/app/Services/AuthService.php +++ b/app/Services/AuthService.php @@ -25,6 +25,13 @@ class AuthService $this->accountRepo = $repo; } + public static function getProviders() + { + $providers = []; + + + } + public function execute($provider, $hasCode) { if (!$hasCode) { @@ -46,7 +53,8 @@ class AuthService if ($result === true) { if (!$isRegistered) { event(new UserSignedUp()); - Session::flash('message', trans('texts.success_message')); + Session::flash('warning', trans('texts.success_message')); + Session::flash('onReady', 'handleSignedUp();'); } else { Session::flash('message', trans('texts.updated_settings')); return redirect()->to('/settings/' . ACCOUNT_USER_DETAILS); diff --git a/app/Services/PaymentService.php b/app/Services/PaymentService.php index e9d99fc7ee..ce67c3fe5e 100644 --- a/app/Services/PaymentService.php +++ b/app/Services/PaymentService.php @@ -33,7 +33,7 @@ class PaymentService extends BaseService public function createGateway($accountGateway) { $gateway = Omnipay::create($accountGateway->gateway->provider); - $config = json_decode($accountGateway->config); + $config = $accountGateway->getConfig(); foreach ($config as $key => $val) { if (!$val) { diff --git a/database/migrations/2015_11_01_080417_encrypt_tokens.php b/database/migrations/2015_11_01_080417_encrypt_tokens.php new file mode 100644 index 0000000000..0f2c35d4fc --- /dev/null +++ b/database/migrations/2015_11_01_080417_encrypt_tokens.php @@ -0,0 +1,41 @@ +get(['id', 'config']); + foreach ($gateways as $gateway) { + DB::table('account_gateways') + ->where('id', $gateway->id) + ->update(['config' => Crypt::encrypt($gateway->config)]); + } + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + $gateways = DB::table('account_gateways') + ->get(['id', 'config']); + foreach ($gateways as $gateway) { + DB::table('account_gateways') + ->where('id', $gateway->id) + ->update(['config' => Crypt::decrypt($gateway->config)]); + } + + } + +} diff --git a/resources/lang/en/texts.php b/resources/lang/en/texts.php index cf367e5ad5..a39ec60438 100644 --- a/resources/lang/en/texts.php +++ b/resources/lang/en/texts.php @@ -889,4 +889,6 @@ return array( 'default_invoice_terms' => 'Default Invoice Terms', 'default_invoice_footer' => 'Default Invoice Footer', 'quote_footer' => 'Quote Footer', + 'free' => 'Free', + ); diff --git a/resources/views/accounts/user_details.blade.php b/resources/views/accounts/user_details.blade.php index 071b95cb9f..2066e0d79a 100644 --- a/resources/views/accounts/user_details.blade.php +++ b/resources/views/accounts/user_details.blade.php @@ -38,7 +38,7 @@
- @if (Utils::isNinja()) + @if (Utils::isOAuthEnabled()) {!! Former::plaintext('oneclick_login')->value( $user->oauth_provider_id ? $oauthProviderName . ' - ' . link_to('#', trans('texts.disable'), ['onclick' => 'disableSocialLogin()']) : @@ -49,10 +49,14 @@ @if (Utils::isNinja()) @if ($user->referral_code) + {{ Former::setOption('capitalize_translations', false) }} {!! Former::plaintext('referral_code') - ->help(trans('texts.referral_code_help')) - ->value($user->referral_code . ' ' . Icon::create('question-sign') . '') !!} - @elseif (Input::has('affiliate')) + ->help(NINJA_APP_URL . '/invoice_now?rc=' . $user->referral_code) + ->value($user->referral_code . ' - '. + $referralCounts['free'] . ' ' . trans('texts.free') . ' | ' . + $referralCounts['pro'] . ' ' . trans('texts.pro') . ' ' . + '' . Icon::create('question-sign') . '') !!} + @else {!! Former::checkbox('referral_code') ->help(trans('texts.referral_code_help')) ->text(trans('texts.enable') . ' ' . Icon::create('question-sign') . '') !!} diff --git a/resources/views/auth/login.blade.php b/resources/views/auth/login.blade.php index bdda6f1b65..33e2d84add 100644 --- a/resources/views/auth/login.blade.php +++ b/resources/views/auth/login.blade.php @@ -89,16 +89,16 @@ @if (Input::get('new_company') && Utils::allowNewAccounts())

- {{ trans('texts.or') }} -

{!! Button::primary(trans('texts.new_company'))->asLinkTo(URL::to('/invoice_now?new_company=true&sign_up=true'))->large()->submit()->block() !!}


- @elseif (Utils::isNinja()) + @elseif (Utils::isOAuthEnabled())

- {{ trans('texts.or') }} -

@foreach (App\Services\AuthService::$providers as $provider) +
+
@endforeach @endif diff --git a/resources/views/header.blade.php b/resources/views/header.blade.php index a196d84f5b..b8d257752e 100644 --- a/resources/views/header.blade.php +++ b/resources/views/header.blade.php @@ -122,22 +122,25 @@ '&go_pro=' + $('#go_pro').val(), success: function(result) { if (result) { - localStorage.setItem('guest_key', ''); - fbq('track', 'CompleteRegistration'); - window._fbq.push(['track', '{{ env('FACEBOOK_PIXEL_SIGN_UP') }}', {'value':'0.00','currency':'USD'}]); - trackEvent('/account', '/signed_up'); + handleSignedUp(); NINJA.isRegistered = true; $('#signUpButton').hide(); - $('#myAccountButton').html(result); - } + $('#myAccountButton').html(result); + } $('#signUpSuccessDiv, #signUpFooter, #closeSignUpButton').show(); $('#working, #saveSignUpButton').hide(); } - }); - } - + }); + } @endif + function handleSignedUp() { + localStorage.setItem('guest_key', ''); + fbq('track', 'CompleteRegistration'); + window._fbq.push(['track', '{{ env('FACEBOOK_PIXEL_SIGN_UP') }}', {'value':'0.00','currency':'USD'}]); + trackEvent('/account', '/signed_up'); + } + function checkForEnter(event) { if (event.keyCode === 13){ @@ -245,7 +248,12 @@ } function setSignupEnabled(enabled) { - $('.signup-form input[type=text], .signup-form button').prop('disabled', !enabled); + $('.signup-form input[type=text]').prop('disabled', !enabled); + if (enabled) { + $('.signup-form a.btn').removeClass('disabled'); + } else { + $('.signup-form a.btn').addClass('disabled'); + } } function setSocialLoginProvider(provider) { @@ -550,7 +558,7 @@ {!! Former::checkbox('terms_checkbox')->label(' ')->text(trans('texts.agree_to_terms', ['terms' => ''.trans('texts.terms_of_service').'']))->raw() !!}
- @if (Utils::isNinja()) + @if (Utils::isOAuthEnabled())

{{ trans('texts.sign_up_using') }}


@foreach (App\Services\AuthService::$providers as $provider) diff --git a/resources/views/master.blade.php b/resources/views/master.blade.php index f53c2f40e7..0227c9eed5 100644 --- a/resources/views/master.blade.php +++ b/resources/views/master.blade.php @@ -159,6 +159,10 @@ window._fbq.push(['track', '{{ env('FACEBOOK_PIXEL_BUY_PRO') }}', {'value':'{{ PRO_PLAN_PRICE }}.00','currency':'USD'}]); @endif @endif + + @if (Session::has('onReady')) + {{ Session::get('onReady') }} + @endif }); $('form').submit(function() { NINJA.formIsChanged = false; diff --git a/resources/views/payments/payment.blade.php b/resources/views/payments/payment.blade.php index 374b5ef5a8..5bd3fe442a 100644 --- a/resources/views/payments/payment.blade.php +++ b/resources/views/payments/payment.blade.php @@ -342,6 +342,7 @@ header h3 em { }); $('#country_id').combobox(); + $('#first_name').focus(); }); diff --git a/tests/functional/SettingsCest.php b/tests/functional/SettingsCest.php index f19a920c34..7de52ef9d9 100644 --- a/tests/functional/SettingsCest.php +++ b/tests/functional/SettingsCest.php @@ -112,6 +112,7 @@ class SettingsCest $I->seeRecord('products', array('product_key' => $productKey)); } + /* public function updateNotifications(FunctionalTester $I) { $I->wantTo('update notification settings'); @@ -126,7 +127,8 @@ class SettingsCest $I->seeResponseCodeIs(200); $I->seeRecord('accounts', array('invoice_terms' => $terms)); } - + */ + public function updateInvoiceDesign(FunctionalTester $I) { $I->wantTo('update invoice design'); @@ -231,7 +233,7 @@ class SettingsCest $I->see('Successfully created gateway'); $I->seeRecord('account_gateways', array('gateway_id' => 23)); } else { - $config = json_decode($gateway->config); + $config = $gateway->getConfig(); $apiKey = $config->apiKey; }