diff --git a/app/Constants.php b/app/Constants.php index 397527a0767e..29a7a3d053ad 100644 --- a/app/Constants.php +++ b/app/Constants.php @@ -14,6 +14,8 @@ if (! defined('APP_NAME')) { define('CONTACT_EMAIL', env('MAIL_FROM_ADDRESS')); define('CONTACT_NAME', env('MAIL_FROM_NAME')); define('SITE_URL', env('APP_URL')); + define('APP_VERSION', env('APP_VERSION')); + define('NINJA_TERMS_VERSION', '1.0.1'); define('ENV_DEVELOPMENT', 'local'); define('ENV_STAGING', 'staging'); @@ -24,6 +26,7 @@ if (! defined('APP_NAME')) { define('BANK_LIBRARY_OFX', 1); define('MULTI_DBS', serialize(['db-ninja-1', 'db-ninja-2'])); + define('RANDOM_KEY_LENGTH', 32); //63340286662973277706162286946811886609896461828096 combinations define('SOCIAL_GOOGLE', 'Google'); define('SOCIAL_FACEBOOK', 'Facebook'); @@ -31,4 +34,18 @@ if (! defined('APP_NAME')) { define('SOCIAL_LINKEDIN', 'LinkedIn'); define('SOCIAL_TWITTER', 'Twitter'); define('SOCIAL_BITBUCKET', 'Bitbucket'); + + define('CURRENCY_DOLLAR', 1); + define('CURRENCY_EURO', 3); + + define('DEFAULT_TIMEZONE', 'US/Eastern'); + define('DEFAULT_COUNTRY', 840); // United Stated + define('DEFAULT_CURRENCY', CURRENCY_DOLLAR); + define('DEFAULT_LANGUAGE', 1); // English + define('DEFAULT_DATE_FORMAT', 'M j, Y'); + define('DEFAULT_DATE_PICKER_FORMAT', 'M d, yyyy'); + define('DEFAULT_DATETIME_FORMAT', 'F j, Y g:i a'); + define('DEFAULT_DATETIME_MOMENT_FORMAT', 'MMM D, YYYY h:mm:ss a'); + define('DEFAULT_LOCALE', 'en'); + define('DEFAULT_MAP_ZOOM', 10); } \ No newline at end of file diff --git a/app/Http/Controllers/SignupController.php b/app/Http/Controllers/SignupController.php index 56c29d8d86cb..3ae50fb2a65d 100644 --- a/app/Http/Controllers/SignupController.php +++ b/app/Http/Controllers/SignupController.php @@ -3,6 +3,10 @@ namespace App\Http\Controllers; use App\Http\Requests\SignupRequest; +use App\Models\Account; +use App\Models\User; +use App\Models\UserAccount; +use Illuminate\Support\Facades\Hash; /** * Class SignupController @@ -32,7 +36,39 @@ class SignupController extends Controller */ public function processSignup(SignupRequest $request) { - dd($request->validated()); + //dd($request->validated()); + + //created new account + + $ac = new Account(); + $ac->name = $request->first_name. ' ' .$request->last_name; + $ac->account_key = strtolower(str_random(RANDOM_KEY_LENGTH)); + $ac->ip = $request->ip(); + $ac->save(); + + $user = new User(); + $user->password = Hash::make($request->input('password')); + $user->accepted_terms_version = NINJA_TERMS_VERSION; + $user->db = config('database.default'); + $user->fill($request->all()); + $user->save(); + + $user_account = new UserAccount(); + $user_account->user_id = $user->id; + $user_account->account_id = $ac->id; + $user_account->is_owner = TRUE; + $user_account->is_admin = TRUE; + $user_account->is_default = TRUE; + $user_account->is_locked = FALSE; + $user_account->permissions = ''; + $user_account->save(); + + dd($user); + //log user in + + //fire account created job + + //redirect to localization setup workflow } } \ No newline at end of file diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php index acb9b25f2264..01ef8675049b 100644 --- a/app/Http/Kernel.php +++ b/app/Http/Kernel.php @@ -42,7 +42,7 @@ class Kernel extends HttpKernel 'bindings', ], 'db' => [ - + \App\Http\Middleware\SetDb::class, ], ]; diff --git a/app/Http/Middleware/setDb.php b/app/Http/Middleware/setDb.php index ea643206c5d3..09b6a03fa77c 100644 --- a/app/Http/Middleware/setDb.php +++ b/app/Http/Middleware/setDb.php @@ -5,7 +5,7 @@ namespace App\Http\Middleware; use App\Libraries\MultiDB; use Closure; -class setDb +class SetDb { /** * Handle an incoming request. @@ -16,9 +16,9 @@ class setDb */ public function handle($request, Closure $next) { - if (!config('auth.providers.users.driver') == 'eloquent') { - - //MultiDB::setDB(auth()->user()->) + if (! config('auth.providers.users.driver') == 'eloquent') + { + MultiDB::setDB(auth()->user()->db); } return $next($request); diff --git a/app/Http/Requests/SignupRequest.php b/app/Http/Requests/SignupRequest.php index 5a296a153fc2..8f31e4af4fa5 100644 --- a/app/Http/Requests/SignupRequest.php +++ b/app/Http/Requests/SignupRequest.php @@ -4,6 +4,7 @@ namespace App\Http\Requests; use App\Http\ValidationRules\UniqueUserRule; use Illuminate\Support\Facades\Auth; +use Illuminate\Support\Facades\Hash; class SignupRequest extends Request { @@ -15,7 +16,7 @@ class SignupRequest extends Request */ public function authorize() { - return ! Auth::user(); + return ! auth()->user(); } /** @@ -35,4 +36,14 @@ class SignupRequest extends Request 'terms_of_service' => 'required' ]; } + + public function sanitize() + { + $input = $this->all(); + + // $this->replace($input); + + return $this->all(); + } + } \ No newline at end of file diff --git a/app/Libraries/MultiDB.php b/app/Libraries/MultiDB.php index 5ed64cb50c98..98f4ccbacc0b 100644 --- a/app/Libraries/MultiDB.php +++ b/app/Libraries/MultiDB.php @@ -63,9 +63,8 @@ class MultiDB */ public static function setDB($database) : void { - /* This will set the default configuration for the request */ + /* This will set the database connection for the request */ config(['database.default' => $database]); - app('db')->connection(config('database.connections.database.'.$database)); } } \ No newline at end of file diff --git a/app/Models/User.php b/app/Models/User.php index bbbbba980099..d91261fae2a2 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -13,6 +13,9 @@ class User extends Authenticatable use SoftDeletes; protected $guard = 'user'; + + protected $dates = ['deleted_at']; + /** * The attributes that are mass assignable. * @@ -22,10 +25,10 @@ class User extends Authenticatable 'first_name', 'last_name', 'email', - 'password', 'phone', 'signature', 'avatar', + 'accepted_terms_version' ]; /** @@ -34,7 +37,6 @@ class User extends Authenticatable * @var array */ protected $hidden = [ - 'password', 'remember_token', 'confirmation_code', 'oauth_user_id', diff --git a/composer.json b/composer.json index e57a946f9ab2..fa0151d5a3ab 100644 --- a/composer.json +++ b/composer.json @@ -25,6 +25,8 @@ "laravel/framework": "5.7.*", "laravel/socialite": "^3.1", "laravel/tinker": "^1.0", + "nwidart/laravel-modules": "^4.0", + "predis/predis": "^1.1", "spatie/laravel-html": "^2.19", "webpatser/laravel-countries": "dev-master#75992ad" }, diff --git a/composer.lock b/composer.lock index 1a53cb7052e1..51e3d22bfd44 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "0a3a5aeaabd9e3362e0da55be647367c", + "content-hash": "b059d33c67d5ecfe4b761dbc55f4e326", "packages": [ { "name": "asgrim/ofxparser", @@ -1347,6 +1347,76 @@ ], "time": "2018-10-10T09:24:14+00:00" }, + { + "name": "nwidart/laravel-modules", + "version": "4.0.0", + "source": { + "type": "git", + "url": "https://github.com/nWidart/laravel-modules.git", + "reference": "d487d9be3bfd6b7365678fd805d9ba5f0dd8295c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nWidart/laravel-modules/zipball/d487d9be3bfd6b7365678fd805d9ba5f0dd8295c", + "reference": "d487d9be3bfd6b7365678fd805d9ba5f0dd8295c", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^2.7", + "laravel/framework": "5.7.*", + "mockery/mockery": "~1.0", + "orchestra/testbench": "^3.7", + "phpstan/phpstan": "^0.9.2", + "phpunit/phpunit": "~7.3", + "spatie/phpunit-snapshot-assertions": "^1.0" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Nwidart\\Modules\\LaravelModulesServiceProvider" + ], + "aliases": { + "Module": "Nwidart\\Modules\\Facades\\Module" + } + }, + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "psr-4": { + "Nwidart\\Modules\\": "src" + }, + "files": [ + "src/helpers.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Widart", + "email": "n.widart@gmail.com", + "homepage": "https://nicolaswidart.com", + "role": "Developer" + } + ], + "description": "Laravel Module management", + "keywords": [ + "laravel", + "module", + "modules", + "nwidart", + "rad" + ], + "time": "2018-09-30T10:02:46+00:00" + }, { "name": "opis/closure", "version": "3.1.1", @@ -1453,6 +1523,56 @@ ], "time": "2018-07-02T15:55:56+00:00" }, + { + "name": "predis/predis", + "version": "v1.1.1", + "source": { + "type": "git", + "url": "https://github.com/nrk/predis.git", + "reference": "f0210e38881631afeafb56ab43405a92cafd9fd1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nrk/predis/zipball/f0210e38881631afeafb56ab43405a92cafd9fd1", + "reference": "f0210e38881631afeafb56ab43405a92cafd9fd1", + "shasum": "" + }, + "require": { + "php": ">=5.3.9" + }, + "require-dev": { + "phpunit/phpunit": "~4.8" + }, + "suggest": { + "ext-curl": "Allows access to Webdis when paired with phpiredis", + "ext-phpiredis": "Allows faster serialization and deserialization of the Redis protocol" + }, + "type": "library", + "autoload": { + "psr-4": { + "Predis\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Daniele Alessandri", + "email": "suppakilla@gmail.com", + "homepage": "http://clorophilla.net" + } + ], + "description": "Flexible and feature-complete Redis client for PHP and HHVM", + "homepage": "http://github.com/nrk/predis", + "keywords": [ + "nosql", + "predis", + "redis" + ], + "time": "2016-06-16T16:22:20+00:00" + }, { "name": "psr/container", "version": "1.0.0", diff --git a/config/ninja.php b/config/ninja.php index 526feb30e9ca..d2028d50554e 100644 --- a/config/ninja.php +++ b/config/ninja.php @@ -5,5 +5,17 @@ return [ 'web_url' => 'https://www.invoiceninja.com', 'app_url' => 'https://app-v5.invoiceninja.com', 'site_url' => '', + 'environment' => env('NINJA_ENVIRONMENT', 'selfhost'), // 'hosted', 'development', 'selfhost', 'reseller' + // Settings used by invoiceninja.com + + 'terms_of_service_url' => [ + 'hosted' => env('TERMS_OF_SERVICE_URL', 'https://www.invoiceninja.com/terms/'), + 'selfhost' => env('TERMS_OF_SERVICE_URL', 'https://www.invoiceninja.com/self-hosting-terms-service/'), + ], + + 'privacy_policy_url' => [ + 'hosted' => env('PRIVACY_POLICY_URL', 'https://www.invoiceninja.com/privacy-policy/'), + 'selfhost' => env('PRIVACY_POLICY_URL', 'https://www.invoiceninja.com/self-hosting-privacy-data-control/'), + ], ]; diff --git a/database/factories/ContactFactory.php b/database/factories/ContactFactory.php index 63c061a3f8d2..80dfb6758720 100644 --- a/database/factories/ContactFactory.php +++ b/database/factories/ContactFactory.php @@ -15,9 +15,10 @@ use Faker\Generator as Faker; $factory->define(App\Models\Contact::class, function (Faker $faker) { return [ - 'first_name' => $faker->name, - 'email' => $faker->unique()->safeEmail, - 'password' => bcrypt('secret'), - 'remember_token' => str_random(10), + 'first_name' => $faker->name, + 'email' => $faker->unique()->safeEmail, + 'password' => bcrypt('secret'), + 'remember_token' => str_random(10), + 'db' => config('database.default') ]; }); diff --git a/database/factories/UserFactory.php b/database/factories/UserFactory.php index c181b4e84101..2e0c4dc3f5a9 100644 --- a/database/factories/UserFactory.php +++ b/database/factories/UserFactory.php @@ -22,5 +22,6 @@ $factory->define(App\Models\User::class, function (Faker $faker) { 'email_verified_at' => now(), 'password' => '$2y$10$TKh8H1.PfQx37YgCzwiKb.KjNyWgaHb9cbcoQgdIVFlYg7B77UdFm', // secret 'remember_token' => str_random(10), + 'db' => config('database.default') ]; }); diff --git a/database/migrations/2018_10_18_210819_add_db_to_user_table.php b/database/migrations/2018_10_18_210819_add_db_to_user_table.php new file mode 100644 index 000000000000..c6eb1450b055 --- /dev/null +++ b/database/migrations/2018_10_18_210819_add_db_to_user_table.php @@ -0,0 +1,63 @@ +string('db', 100); + }); + + Schema::table('contacts', function (Blueprint $table) { + $table->string('db', 100); + }); + + Schema::table('users', function (Blueprint $table){ + $table->dropColumn('confirmed'); + $table->dropColumn('registered'); + }); + + Schema::table('contacts', function (Blueprint $table){ + $table->dropColumn('confirmed'); + $table->dropColumn('registered'); + + }); + + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('users', function (Blueprint $table) { + $table->dropColumn('db'); + }); + + Schema::table('contacts', function (Blueprint $table) { + $table->dropColumn('db'); + }); + + Schema::table('users', function (Blueprint $table){ + $table->boolean('confirmed'); + $table->boolean('registered'); + }); + + Schema::table('contacts', function (Blueprint $table){ + $table->boolean('confirmed'); + $table->boolean('registered'); + + }); + } +} diff --git a/resources/views/signup/index.blade.php b/resources/views/signup/index.blade.php index a624ff64b428..b6500144da04 100644 --- a/resources/views/signup/index.blade.php +++ b/resources/views/signup/index.blade.php @@ -70,7 +70,7 @@ - + has('password') ? ' is-invalid' : '' }} name="password" placeholder="@lang('texts.password')" required> @if ($errors->has('password')) @@ -79,17 +79,19 @@ @endif -
- +
+
-
- +
+
@@ -137,6 +139,4 @@ - - \ No newline at end of file diff --git a/routes/web.php b/routes/web.php index e8a1954a9b26..817432fca63d 100644 --- a/routes/web.php +++ b/routes/web.php @@ -1,58 +1,45 @@ name('login'); Route::post('login', 'Auth\LoginController@login'); Route::post('logout', 'Auth\LoginController@logout')->name('logout'); - -// Social authentication - -Route::get('auth/{provider}', 'Auth\LoginController@redirectToProvider'); -Route::get('auth/{provider}/callback', 'Auth\LoginController@handleProviderCallback'); - -// Password Reset Routes... +/* + * Signup Routes + */ +Route::redirect('/', '/login', 301); +Route::get('signup', 'SignupController@signup')->name('signup'); +Route::post('process_signup', 'SignupController@processSignup')->name('signup.submit'); +Route::get('contact/login', 'Auth\ContactLoginController@showLoginForm')->name('contact.login'); +Route::post('contact/login', 'Auth\ContactLoginController@login')->name('contact.login.submit'); +/* + * Password Reset Routes... + */ Route::get('password/reset', 'Auth\ForgotPasswordController@showLinkRequestForm')->name('password.request'); Route::post('password/email', 'Auth\ForgotPasswordController@sendResetLinkEmail')->name('password.email'); Route::get('password/reset/{token}', 'Auth\ResetPasswordController@showResetForm')->name('password.reset'); Route::post('password/reset', 'Auth\ResetPasswordController@reset')->name('password.update'); - /* -Open Routes + * Social authentication */ -//Route::get('/', 'HomeController@index')->name('default'); -Route::redirect('/', '/login', 301); - - -Route::get('/signup', 'SignupController@signup')->name('signup'); -Route::post('/process_signup', 'SignupController@processSignup')->name('signup.submit'); - -Route::get('/contact/login', 'Auth\ContactLoginController@showLoginForm')->name('contact.login'); -Route::post('/contact/login', 'Auth\ContactLoginController@login')->name('contact.login.submit'); - - +Route::get('auth/{provider}', 'Auth\LoginController@redirectToProvider'); +Route::get('auth/{provider}/callback', 'Auth\LoginController@handleProviderCallback'); /* -Authenticated User Routes + * Authenticated User Routes */ Route::group(['middleware' => ['auth:user', 'db']], function () { - Route::get('/dashboard', 'HomeController@user')->name('user.dashboard'); - Route::get('/logout', 'Auth\LoginController@logout')->name('user.logout'); - Route::resource('/invoices', 'InvoiceController'); // name = (invoices. index / create / show / update / destroy / edit - Route::get('/settings', 'SettingsController@index')->name('user.settings'); -}); + Route::get('dashboard', 'HomeController@user')->name('user.dashboard'); + Route::get('logout', 'Auth\LoginController@logout')->name('user.logout'); + Route::resource('invoices', 'InvoiceController'); // name = (invoices. index / create / show / update / destroy / edit + Route::get('settings', 'SettingsController@index')->name('user.settings'); +}); +/* + * Inbound routes requiring DB Lookup + */ /* Authenticated Contact Routes @@ -60,6 +47,6 @@ Authenticated Contact Routes Route::group(['prefix' => 'contact', 'middleware' => 'auth:contact'], function () { Route::get('/', 'ContactController@index')->name('contact.dashboard'); - Route::get('logout/', 'Auth\ContactLoginController@logout')->name('contact.logout'); + Route::get('logout', 'Auth\ContactLoginController@logout')->name('contact.logout'); }); \ No newline at end of file diff --git a/tests/Integration/MultiDBUserTest.php b/tests/Integration/MultiDBUserTest.php index 73dfe520fc1c..b7e67798ff00 100644 --- a/tests/Integration/MultiDBUserTest.php +++ b/tests/Integration/MultiDBUserTest.php @@ -39,7 +39,8 @@ class MultiDBUserTest extends TestCase 'password' => '$2y$10$TKh8H1.PfQx37YgCzwiKb.KjNyWgaHb9cbcoQgdIVFlYg7B77UdFm', // secret 'remember_token' => str_random(10), 'email' => 'db1@example.com', - 'oauth_user_id' => '123' + 'oauth_user_id' => '123', + 'db' => config('database.default') ]; @@ -51,7 +52,9 @@ class MultiDBUserTest extends TestCase 'password' => '$2y$10$TKh8H1.PfQx37YgCzwiKb.KjNyWgaHb9cbcoQgdIVFlYg7B77UdFm', // secret 'remember_token' => str_random(10), 'email' => 'db2@example.com', - 'oauth_user_id' => 'abc' + 'oauth_user_id' => 'abc', + 'db' => config('database.default') + ]; User::on('db-ninja-1')->create($user); diff --git a/tests/Integration/UniqueEmailTest.php b/tests/Integration/UniqueEmailTest.php index dc9f2fc41239..ec332d64195e 100644 --- a/tests/Integration/UniqueEmailTest.php +++ b/tests/Integration/UniqueEmailTest.php @@ -34,9 +34,11 @@ class UniqueEmailTest extends TestCase $this->rule = new UniqueUserRule(); $user = [ - 'first_name' => 'user_db_1', - 'email' => 'user@example.com', - 'password' => Hash::make('password'), + 'first_name' => 'user_db_1', + 'email' => 'user@example.com', + 'password' => Hash::make('password'), + 'db' => config('database.default') + ]; User::on('db-ninja-1')->create($user);