diff --git a/app/Http/Controllers/SettingsController.php b/app/Http/Controllers/SettingsController.php index 940da033aa..c42dfd0975 100644 --- a/app/Http/Controllers/SettingsController.php +++ b/app/Http/Controllers/SettingsController.php @@ -6,38 +6,31 @@ use App\Helpers\Helper; use App\Helpers\StorageHelper; use App\Http\Requests\ImageUploadRequest; use App\Http\Requests\SettingsSamlRequest; -use App\Http\Requests\SetupUserRequest; +use App\Http\Requests\StoreLabelSettings; use App\Http\Requests\StoreLdapSettings; use App\Http\Requests\StoreLocalizationSettings; use App\Http\Requests\StoreNotificationSettings; -use App\Http\Requests\StoreLabelSettings; use App\Http\Requests\StoreSecuritySettings; +use App\Models\Asset; use App\Models\CustomField; use App\Models\Group; -use App\Models\Labels\Label as LabelModel; use App\Models\Setting; -use App\Models\Asset; use App\Models\User; -use App\Notifications\FirstAdminNotification; use App\Notifications\MailTest; -use Illuminate\Http\Request; -use Illuminate\Support\Facades\App; -use Illuminate\Support\Facades\Storage; -use Illuminate\Validation\Rule; -use Illuminate\Http\RedirectResponse; use Illuminate\Http\JsonResponse; -use \Illuminate\Contracts\View\View; -use Illuminate\Support\Str; +use Illuminate\Http\RedirectResponse; +use Illuminate\Http\Request; use Illuminate\Support\Facades\Artisan; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Crypt; use Illuminate\Support\Facades\DB; -use Illuminate\Support\Facades\File; -use Illuminate\Support\Facades\Http; use Illuminate\Support\Facades\Log; -use Illuminate\Support\Facades\URL; +use Illuminate\Support\Facades\Storage; use Illuminate\Support\Facades\Validator; +use Illuminate\Support\Str; +use Illuminate\Validation\Rule; use Symfony\Component\HttpFoundation\BinaryFileResponse; +use \Illuminate\Contracts\View\View; /** * This controller handles all actions related to Settings for @@ -47,224 +40,6 @@ use Symfony\Component\HttpFoundation\BinaryFileResponse; */ class SettingsController extends Controller { - /** - * Checks to see whether or not the database has a migrations table - * and a user, otherwise display the setup view. - * - * @author [A. Gianotto] [] - * - * @since [v3.0] - * - * @return \Illuminate\Contracts\View\View | \Illuminate\Http\Response - */ - public function getSetupIndex() : View - { - $start_settings['php_version_min'] = false; - - if (version_compare(PHP_VERSION, config('app.min_php'), '<')) { - return response('

This software requires PHP version '.config('app.min_php').' or greater. This server is running '.PHP_VERSION.'.

Please upgrade PHP on this server and try again.

', 500); - } - - try { - $conn = DB::select('select 2 + 2'); - $start_settings['db_conn'] = true; - $start_settings['db_name'] = DB::connection()->getDatabaseName(); - $start_settings['db_error'] = null; - } catch (\PDOException $e) { - $start_settings['db_conn'] = false; - $start_settings['db_name'] = config('database.connections.mysql.database'); - $start_settings['db_error'] = $e->getMessage(); - } - - $start_settings['url_config'] = trim(config('app.url'), '/'). '/setup'; - $start_settings['real_url'] = request()->url(); - $start_settings['url_valid'] = $start_settings['url_config'] === $start_settings['real_url']; - $start_settings['php_version_min'] = true; - - // Curl the .env file to make sure it's not accessible via a browser - $start_settings['env_exposed'] = $this->dotEnvFileIsExposed(); - - if (App::Environment('production') && (true == config('app.debug'))) { - $start_settings['debug_exposed'] = true; - } else { - $start_settings['debug_exposed'] = false; - } - - $environment = app()->environment(); - if ('production' != $environment) { - $start_settings['env'] = $environment; - $start_settings['prod'] = false; - } else { - $start_settings['env'] = $environment; - $start_settings['prod'] = true; - } - - $start_settings['owner'] = ''; - - if (function_exists('posix_getpwuid')) { // Probably Linux - $owner = posix_getpwuid(fileowner($_SERVER['SCRIPT_FILENAME'])); - // This *should* be an array, but we've seen this return a bool in some chrooted environments - if (is_array($owner)) { - $start_settings['owner'] = $owner['name']; - } - } - - if (($start_settings['owner'] === 'root') || ($start_settings['owner'] === '0')) { - $start_settings['owner_is_admin'] = true; - } else { - $start_settings['owner_is_admin'] = false; - } - - $start_settings['writable'] = $this->storagePathIsWritable(); - - $start_settings['gd'] = extension_loaded('gd'); - - return view('setup/index') - ->with('step', 1) - ->with('start_settings', $start_settings) - ->with('section', 'Pre-Flight Check'); - } - - /** - * Determine if the .env file accessible via a browser. - * - * @return bool This method will return true when exceptions (such as curl exception) is thrown. - * Check the log files to see more details about the exception. - */ - protected function dotEnvFileIsExposed() : bool - { - try { - return Http::withoutVerifying()->timeout(10) - ->accept('*/*') - ->get(URL::to('.env')) - ->successful(); - } catch (\Exception $e) { - Log::debug($e->getMessage()); - return true; - } - } - - /** - * Determine if the app storage path is writable. - */ - protected function storagePathIsWritable(): bool - { - return File::isWritable(storage_path()) && - File::isWritable(storage_path('framework')) && - File::isWritable(storage_path('framework/cache')) && - File::isWritable(storage_path('framework/sessions')) && - File::isWritable(storage_path('framework/views')) && - File::isWritable(storage_path('logs')); - } - - /** - * Save the first admin user from Setup. - * - * @author [A. Gianotto] [] - * @since [v3.0] - * - */ - public function postSaveFirstAdmin(SetupUserRequest $request) : RedirectResponse - { - - $user = new User(); - $user->first_name = $data['first_name'] = $request->input('first_name'); - $user->last_name = $request->input('last_name'); - $user->email = $data['email'] = $request->input('email'); - $user->activated = 1; - $permissions = ['superuser' => 1]; - $user->permissions = json_encode($permissions); - $user->username = $data['username'] = $request->input('username'); - $user->password = bcrypt($request->input('password')); - $data['password'] = $request->input('password'); - - $settings = new Setting(); - $settings->full_multiple_companies_support = $request->input('full_multiple_companies_support', 0); - $settings->site_name = $request->input('site_name'); - $settings->alert_email = $request->input('email'); - $settings->alerts_enabled = 1; - $settings->pwd_secure_min = 10; - $settings->brand = 1; - $settings->locale = $request->input('locale', 'en-US'); - $settings->default_currency = $request->input('default_currency', 'USD'); - $settings->created_by = 1; - $settings->email_domain = $request->input('email_domain'); - $settings->email_format = $request->input('email_format'); - $settings->next_auto_tag_base = 1; - $settings->auto_increment_assets = $request->input('auto_increment_assets', 0); - $settings->auto_increment_prefix = $request->input('auto_increment_prefix'); - $settings->zerofill_count = $request->input('zerofill_count') ?: 0; - - if ((! $user->isValid()) || (! $settings->isValid())) { - return redirect()->back()->withInput()->withErrors($user->getErrors())->withErrors($settings->getErrors()); - } else { - $user->save(); - Auth::login($user, true); - $settings->save(); - - if ($request->input('email_creds') == '1') { - $data = []; - $data['email'] = $user->email; - $data['username'] = $user->username; - $data['first_name'] = $user->first_name; - $data['last_name'] = $user->last_name; - $data['password'] = $request->input('password'); - $user->notify(new FirstAdminNotification($data)); - } - - return redirect()->route('setup.done'); - } - } - - /** - * Return the admin user creation form in Setup. - * - * @author [A. Gianotto] [] - * - * @since [v3.0] - */ - public function getSetupUser() : View - { - return view('setup/user') - ->with('step', 3) - ->with('section', 'Create a User'); - } - - /** - * Return the view that tells the user that the Setup is done. - * - * @author [A. Gianotto] [] - * - * @since [v3.0] - */ - public function getSetupDone() : View - { - return view('setup/done') - ->with('step', 4) - ->with('section', 'Done!'); - } - - /** - * Migrate the database tables, and return the output - * to a view for Setup. - * - * @author [A. Gianotto] [] - * - * @since [v3.0] - */ - public function getSetupMigrate() : View - { - Artisan::call('migrate', ['--force' => true]); - if ((! file_exists(storage_path().'/oauth-private.key')) || (! file_exists(storage_path().'/oauth-public.key'))) { - Artisan::call('migrate', ['--path' => 'vendor/laravel/passport/database/migrations', '--force' => true]); - Artisan::call('passport:install', ['--no-interaction' => true]); - } - - return view('setup/migrate') - ->with('output', 'Databases installed!') - ->with('step', 2) - ->with('section', 'Create Database Tables'); - } /** * Return a view that shows some of the key settings. diff --git a/app/Http/Controllers/SetupController.php b/app/Http/Controllers/SetupController.php new file mode 100644 index 0000000000..a81da7b9ff --- /dev/null +++ b/app/Http/Controllers/SetupController.php @@ -0,0 +1,270 @@ +] + * + * @since [v3.0] + * + * @return \Illuminate\Contracts\View\View | \Illuminate\Http\Response + */ + public function getSetupIndex() : View + { + $start_settings['php_version_min'] = false; + + if (version_compare(PHP_VERSION, config('app.min_php'), '<')) { + return response('

This software requires PHP version '.config('app.min_php').' or greater. This server is running '.PHP_VERSION.'.

Please upgrade PHP on this server and try again.

', 500); + } + + try { + $conn = DB::select('select 2 + 2'); + $start_settings['db_conn'] = true; + $start_settings['db_name'] = DB::connection()->getDatabaseName(); + $start_settings['db_error'] = null; + } catch (\PDOException $e) { + $start_settings['db_conn'] = false; + $start_settings['db_name'] = config('database.connections.mysql.database'); + $start_settings['db_error'] = $e->getMessage(); + } + + $start_settings['url_config'] = trim(config('app.url'), '/'). '/setup'; + $start_settings['real_url'] = request()->url(); + $start_settings['url_valid'] = $start_settings['url_config'] === $start_settings['real_url']; + $start_settings['php_version_min'] = true; + + // Curl the .env file to make sure it's not accessible via a browser + $start_settings['env_exposed'] = $this->dotEnvFileIsExposed(); + + if (App::Environment('production') && (true == config('app.debug'))) { + $start_settings['debug_exposed'] = true; + } else { + $start_settings['debug_exposed'] = false; + } + + $environment = app()->environment(); + if ('production' != $environment) { + $start_settings['env'] = $environment; + $start_settings['prod'] = false; + } else { + $start_settings['env'] = $environment; + $start_settings['prod'] = true; + } + + $start_settings['owner'] = ''; + + if (function_exists('posix_getpwuid')) { // Probably Linux + $owner = posix_getpwuid(fileowner($_SERVER['SCRIPT_FILENAME'])); + // This *should* be an array, but we've seen this return a bool in some chrooted environments + if (is_array($owner)) { + $start_settings['owner'] = $owner['name']; + } + } + + if (($start_settings['owner'] === 'root') || ($start_settings['owner'] === '0')) { + $start_settings['owner_is_admin'] = true; + } else { + $start_settings['owner_is_admin'] = false; + } + + $start_settings['writable'] = $this->storagePathIsWritable(); + + $start_settings['gd'] = extension_loaded('gd'); + + return view('setup/index') + ->with('step', 1) + ->with('start_settings', $start_settings) + ->with('section', trans('general.setup_config_check')) + ->with('icon', 'fa-regular fa-rectangle-list'); + } + + /** + * Determine if the .env file accessible via a browser. + * + * @return bool This method will return true when exceptions (such as curl exception) is thrown. + * Check the log files to see more details about the exception. + */ + protected function dotEnvFileIsExposed() : bool + { + try { + return Http::withoutVerifying()->timeout(10) + ->accept('*/*') + ->get(URL::to('.env')) + ->successful(); + } catch (\Exception $e) { + Log::debug($e->getMessage()); + return true; + } + } + + /** + * Determine if the app storage path is writable. + */ + protected function storagePathIsWritable(): bool + { + return File::isWritable(storage_path()) && + File::isWritable(storage_path('framework')) && + File::isWritable(storage_path('framework/cache')) && + File::isWritable(storage_path('framework/sessions')) && + File::isWritable(storage_path('framework/views')) && + File::isWritable(storage_path('logs')); + } + + /** + * Save the first admin user from Setup. + * + * @author [A. Gianotto] [] + * @since [v3.0] + * + */ + public function postSaveFirstAdmin(SetupUserRequest $request) : RedirectResponse + { + + $user = new User(); + $user->first_name = $data['first_name'] = $request->input('first_name'); + $user->last_name = $request->input('last_name'); + $user->email = $data['email'] = $request->input('email'); + $user->activated = 1; + $permissions = ['superuser' => 1]; + $user->permissions = json_encode($permissions); + $user->username = $data['username'] = $request->input('username'); + $user->password = bcrypt($request->input('password')); + $data['password'] = $request->input('password'); + + $settings = new Setting(); + $settings->full_multiple_companies_support = $request->input('full_multiple_companies_support', 0); + $settings->site_name = $request->input('site_name'); + $settings->alert_email = $request->input('email'); + $settings->alerts_enabled = 1; + $settings->pwd_secure_min = 10; + $settings->brand = 1; + $settings->link_light_color = $request->input('link_light_color', '#296282'); + $settings->link_dark_color = $request->input('link_dark_color', '#296282'); + $settings->nav_link_color = $request->input('nav_link_color', '#FFFFFF'); + $settings->locale = $request->input('locale', 'en-US'); + $settings->default_currency = $request->input('default_currency', 'USD'); + $settings->created_by = 1; + $settings->email_domain = $request->input('email_domain'); + $settings->email_format = $request->input('email_format'); + $settings->next_auto_tag_base = 1; + $settings->auto_increment_assets = $request->input('auto_increment_assets', 0); + $settings->auto_increment_prefix = $request->input('auto_increment_prefix'); + $settings->zerofill_count = $request->input('zerofill_count') ?: 0; + + if ((! $user->isValid()) || (! $settings->isValid())) { + return redirect()->back()->withInput()->withErrors($user->getErrors())->withErrors($settings->getErrors()); + } else { + $user->save(); + Auth::login($user, true); + $settings->save(); + + if ($request->input('email_creds') == '1') { + $data = []; + $data['email'] = $user->email; + $data['username'] = $user->username; + $data['first_name'] = $user->first_name; + $data['last_name'] = $user->last_name; + $data['password'] = $request->input('password'); + $user->notify(new FirstAdminNotification($data)); + } + + return redirect() + ->route('setup.done') + ->with('section', trans('general.setup_create_admin')) + ->with('icon', 'fa-solid fa-champagne-glasses') + ->with('success', trans('admin/settings/general.create_admin_success')); + } + } + + /** + * Return the admin user creation form in Setup. + * + * @author [A. Gianotto] [] + * + * @since [v3.0] + */ + public function getSetupUser() : View + { + return view('setup/user') + ->with('step', 3) + ->with('section', trans('general.setup_create_admin')) + ->with('icon', 'fa-solid fa-user-plus'); + } + + /** + * Return the view that tells the user that the Setup is done. + * + * @author [A. Gianotto] [] + * + * @since [v3.0] + */ + public function getSetupDone() : View + { + return view('setup/done') + ->with('success', trans('general.create_admin_success')) + ->with('step', 4) + ->with('icon', 'fa-solid fa-champagne-glasses fa-shake') + ->with('section', trans('general.setup_done')); + } + + + + /** + * Migrate the database tables, and return the output + * to a view for Setup. + * + * @author [A. Gianotto] [] + * + * @since [v3.0] + */ + public function setupMigrate() + { + Artisan::call('migrate', ['--force' => true]); + $output = Artisan::output(); + if ((! file_exists(storage_path().'/oauth-private.key')) || (! file_exists(storage_path().'/oauth-public.key'))) { + Artisan::call('migrate', ['--path' => 'vendor/laravel/passport/database/migrations', '--force' => true]); + Artisan::call('passport:install', ['--no-interaction' => true]); + } + + return view('setup/migrate') + ->with('success', trans('general.create_admin_success')) + ->with('output', trim($output)) + ->with('step', 2) + ->with('section', trans('general.setup_create_database')) + ->with('icon', 'fa-solid fa-database'); + } + + + + + + + +} diff --git a/app/Http/Requests/SetupUserRequest.php b/app/Http/Requests/SetupUserRequest.php index e88385b745..7de61f939a 100644 --- a/app/Http/Requests/SetupUserRequest.php +++ b/app/Http/Requests/SetupUserRequest.php @@ -28,7 +28,6 @@ class SetupUserRequest extends Request 'username' => 'required|string|min:2|unique:users,username,NULL,deleted_at', 'email' => 'email|unique:users,email', 'password' => 'required|min:8|confirmed', - 'email_domain' => 'required|min:4', ]; } diff --git a/resources/lang/en-US/admin/settings/general.php b/resources/lang/en-US/admin/settings/general.php index c93068e732..ea8a93c9d6 100644 --- a/resources/lang/en-US/admin/settings/general.php +++ b/resources/lang/en-US/admin/settings/general.php @@ -366,13 +366,14 @@ return [ 'employee_number' => 'Employee Number', 'create_admin_user' => 'Create a User ::', 'create_admin_success' => 'Success! Your admin user has been added!', - 'create_admin_redirect' => 'Click here to go to your app login!', + 'create_admin_redirect' => 'Go To Dashboard', 'setup_migrations' => 'Database Migrations ::', 'setup_no_migrations' => 'There was nothing to migrate. Your database tables were already set up!', 'setup_successful_migrations' => 'Your database tables have been created', 'setup_migration_output' => 'Migration output:', - 'setup_migration_create_user' => 'Next: Create User', + 'setup_migration_create_user' => 'Save User and Finish', 'ldap_settings_link' => 'LDAP Settings Page', + 'setup_create_user_page_explanation' => 'Here you will create your first superadmin user and set some basic application setting defaults. (These can always be changed later in the Admin Settings section.) ', 'slack_test' => 'Test Integration', 'status_label_name' => 'Status Label Name', 'super_admin_only' => 'Super Admin Only', diff --git a/resources/lang/en-US/general.php b/resources/lang/en-US/general.php index 97e951b355..47bf1072c1 100644 --- a/resources/lang/en-US/general.php +++ b/resources/lang/en-US/general.php @@ -384,9 +384,10 @@ return [ 'setup_step_3' => 'Step 3', 'setup_step_4' => 'Step 4', 'setup_config_check' => 'Configuration Check', - 'setup_create_database' => 'Create database tables', - 'setup_create_admin' => 'Create an admin user', - 'setup_done' => 'Finished!', + 'setup_create_database' => 'Create Database Tables', + 'setup_create_admin' => 'Create an Admin User', + 'setup_next' => 'Next', + 'setup_done' => 'Setup Complete!', 'bulk_edit_about_to' => 'You are about to edit the following: ', 'checked_out' => 'Checked Out', 'checked_out_to' => 'Checked out to', diff --git a/resources/views/layouts/setup.blade.php b/resources/views/layouts/setup.blade.php index 13270a4d5d..50aeda52e9 100644 --- a/resources/views/layouts/setup.blade.php +++ b/resources/views/layouts/setup.blade.php @@ -31,7 +31,10 @@ } .preflight-error { - color: red; + color: #b60707; + } + .preflight-info { + font-size: 18px; } .preflight-warning { @@ -50,7 +53,26 @@ font-size: 16px; } + body { + background-color: #ecf0f5; + } + .bs-wizard-info { + color: #959495 !important; + } + + h4 { + line-height: 25px; + } + + p, li { + font-size: 15px; + line-height: 25px; + } + + li { + display: block; + } @@ -58,9 +80,9 @@
-

Snipe-IT {{ trans('general.pre_flight') }}

+

Snipe-IT logo {{ trans('general.pre_flight') }}

-
+
@@ -68,13 +90,13 @@
{{ trans('general.setup_step_1') }}
-
{{ trans('general.setup_config_check') }}
+
{{ trans('general.setup_config_check') }}
{{ trans('general.setup_step_2') }}
- +
{{ trans('general.setup_create_database') }}
@@ -94,25 +116,31 @@
+
-
-
- {{ $section }} +
+
+

{{ $section }}

-
+
+ + @include('notifications') + + @yield('content')
- + Snipe-IT {{ trans('general.version') }} {{ config('version.app_version') }} - + {{ trans('general.build') }} {{ config('version.build_version') }} ({{ config('version.branch') }}) +
diff --git a/resources/views/setup/done.blade.php b/resources/views/setup/done.blade.php index f0a0b48509..f4e642f318 100644 --- a/resources/views/setup/done.blade.php +++ b/resources/views/setup/done.blade.php @@ -7,13 +7,104 @@ {{-- Page content --}} @section('content') -
-
-
- - {{ trans('general.create_admin_success') }} + + + +
+ +

+ If you're already familiar with Snipe-IT, you can get started right away by heading right to your dashboard, or if it's your first time using Snipe-IT, you can check out some of the useful resources below: +

+ + +
+ +

+ Important Note Syncing Users via SCIM or LDAP +

+ +

+ If you plan on using SCIM or LDAP syncing to keep your user lists up to date with your directory services, + make sure the username format for any users imported via CSV matches your directory service username format to avoid duplicating users in Snipe-IT. +

+
+ +

+ Don't forget to join our communities! You can find us on: +

+ + + +

+ Subscribe on Github for notifications about new releases. (We recommend selecting "Releases Only" for most users - the repo can get noisy.) +

+
-

{{ trans('general.create_admin_redirect') }} {{ config('app.url') }}

-
+ @stop + +@section('button') + {{ trans('admin/settings/general.create_admin_redirect') }} + + + @parent +@stop + + + diff --git a/resources/views/setup/index.blade.php b/resources/views/setup/index.blade.php index 2eef58aa89..f7c8fce773 100644 --- a/resources/views/setup/index.blade.php +++ b/resources/views/setup/index.blade.php @@ -9,7 +9,7 @@ Create a User :: {{-- Page content --}} @section('content') -

This page will do a system check to make sure your configuration looks correct. We'll add your first user on the next page.

+

First let's do a quick system check to make sure your configuration looks correct.

@@ -162,7 +162,7 @@ Create a User :: @if (!$start_settings['debug_exposed']) Awesomesauce. Debug is either turned off, or you're running this in a non-production environment. (Don't forget to turn it off when you're ready to go live.) @else - Yikes! You should turn off debug mode unless you encounter any issues. Please update your APP_DEBUG settings in your .env file +

Yikes! You should turn off debug mode unless you encounter any issues. Please update your APP_DEBUG settings in your .env file

@endif @@ -178,29 +178,22 @@ Create a User :: - + @@ -209,9 +202,14 @@ Create a User :: @stop @section('button') - - + + @csrf + + @parent @stop @@ -223,12 +221,11 @@ Create a User :: $("#mailtest").click(function(){ - $("#mailtestrow").removeClass('success').removeClass('danger').removeClass('warning'); - $("#mailtestrow").addClass('info'); + $("#mailtestrow").removeClass('success').removeClass('danger').removeClass('warning').addClass('info'); $("#mailtesticon").html(''); - $("#mailteststatus").html(''); + $("#mailteststatus").html('Sending Test Email...'); $('#mailteststatus-error').html(''); - $("#mailtesticon").html(' Sending Test Email...'); + $("#mailtesticon").html(''); $.ajax({ url: "{{ route('setup.mailtest') }}", @@ -237,12 +234,12 @@ Create a User :: if (result.status == 'success') { $("#mailtestrow").removeClass('info').removeClass('danger').removeClass('warning'); $("#mailtestrow").addClass('success'); - $("#mailtesticon").html(''); + $("#mailtesticon").html(''); $("#mailteststatus").html(''); $('#mailteststatus-error').html(''); - $("#mailteststatus").removeClass('text-danger'); - $("#mailteststatus").addClass('text-success'); - $("#mailteststatus").html(' Mail sent to {{ config('mail.from.address') }}!'); + $("#mailteststatus-text").removeClass('text-danger'); + $("#mailteststatus-text").addClass('text-success'); + $("#mailteststatus-text").html('Mail sent to {{ config('mail.from.address') }}!'); } else { $("#mailtestrow").removeClass('success').removeClass('info').removeClass('warning'); $("#mailtestrow").addClass('danger'); @@ -257,12 +254,12 @@ Create a User :: $("#mailtestrow").removeClass('success').removeClass('info').removeClass('warning'); $("#mailtestrow").addClass('danger'); $("#mailtesticon").html(''); - $("#mailteststatus").html(''); + $("#mailteststatus-text").html(''); $('#mailteststatus-error').html(''); - $("#mailteststatus").removeClass('text-success'); - $("#mailteststatus").addClass('text-danger'); + $("#mailteststatus-text").removeClass('text-success'); + $("#mailteststatus-text").addClass('text-danger'); $("#mailtesticon").html(''); - $('#mailteststatus').html('Mail could not be sent.'); + $('#mailteststatus-text').html('Mail could not be sent.'); if (result.responseJSON) { $('#mailteststatus-error').html('Error: ' + result.responseJSON.messages); } else { diff --git a/resources/views/setup/migrate.blade.php b/resources/views/setup/migrate.blade.php index 816ae61491..f99ce05579 100644 --- a/resources/views/setup/migrate.blade.php +++ b/resources/views/setup/migrate.blade.php @@ -1,7 +1,7 @@ @extends('layouts/setup') {{-- Page title --}} @section('title') -{{ trans('general.setup_migrations') }} +{{ trans('admin/settings/general.setup_migrations') }} @parent @stop @@ -15,13 +15,6 @@ {{ trans('general.setup_no_migrations') }} - @else -
-
- - {{ trans('general.setup_successful_migrations') }} -
-
@endif @@ -31,8 +24,11 @@ @stop @section('button') - - - + + + {{ trans('general.setup_next') }}: + {{ trans('general.setup_create_admin') }} + + @parent @stop diff --git a/resources/views/setup/user.blade.php b/resources/views/setup/user.blade.php index 4f6531668d..e47762c09e 100644 --- a/resources/views/setup/user.blade.php +++ b/resources/views/setup/user.blade.php @@ -8,7 +8,11 @@ {{-- Page content --}} @section('content') -

{{ trans('admin/users/general.create_user_page_explanation') }}

+ +
+

{{ trans('admin/settings/general.setup_create_user_page_explanation') }}

+
+ {{ csrf_field() }} @@ -27,7 +31,103 @@ -
+ +
+ +
+ + + {!! $errors->first('first_name', '') !!} +
+ + +
+ + + {!! $errors->first('last_name', '') !!} +
+
+ +
+ +
+ + + {!! $errors->first('email', '') !!} +
+ + +
+ + + {!! $errors->first('username', '') !!} +
+ +
+ +
+ +
+ + + {!! $errors->first('password', '') !!} +
+ + +
+ + + {!! $errors->first('password_confirmation', '') !!} +
+ + +
+ +
+ +
+ + +
+ +
+ + + + {!! $errors->first('auto_increment_prefix', '') !!} +
+ +
+ + + + {!! $errors->first('zerofill_count', '') !!} +
+
+ +
+ +
+ + +
+ + +
+ +
+ +
+ + + +
@@ -48,122 +148,20 @@
-
- -
- - - -
- - -
- -
-
- -
- -
- - - - {!! $errors->first('auto_increment_prefix', '') !!} -
- -
- - - - {!! $errors->first('zerofill_count', '') !!} -
-
- -
-
- - - {{ trans('general.email_domain_help') }} - {!! $errors->first('email_domain', '') !!} -
- -
- - {!! Form::username_format('email_format', old('email_format', 'filastname'), 'select2') !!} - {!! $errors->first('email_format', '') !!} -
-
- - -
- -
- - - {!! $errors->first('first_name', '') !!} -
- - -
- - - {!! $errors->first('last_name', '') !!} -
-
- -
- -
- - - {!! $errors->first('email', '') !!} -
- - -
- - - {!! $errors->first('username', '') !!} -
-
- -
- -
- - - {!! $errors->first('password', '') !!} -
- - -
- - - {!! $errors->first('password_confirmation', '') !!} -
-
- - -
- -
@stop @section('button') - + @parent @stop diff --git a/routes/web.php b/routes/web.php index 9a20322d0e..7065146e9d 100644 --- a/routes/web.php +++ b/routes/web.php @@ -24,6 +24,7 @@ use App\Http\Controllers\ProfileController; use App\Http\Controllers\ReportTemplatesController; use App\Http\Controllers\ReportsController; use App\Http\Controllers\SettingsController; +use App\Http\Controllers\SetupController; use App\Http\Controllers\StatuslabelsController; use App\Http\Controllers\SuppliersController; use App\Http\Controllers\ViewAssetsController; @@ -48,7 +49,7 @@ Route::group(['middleware' => 'auth'], function () { ]); Route::post('categories/bulk/delete', [BulkCategoriesController::class, 'destroy'])->name('categories.bulk.delete'); - + /* * Labels */ @@ -285,15 +286,15 @@ Route::group(['prefix' => 'admin', 'middleware' => ['auth', 'authorize:superuser Route::delete('delete/{filename}', [SettingsController::class, 'deleteFile'])->name('settings.backups.destroy'); - Route::post('/', + Route::post('/', [SettingsController::class, 'postBackups'] )->name('settings.backups.create'); - Route::post('/restore/{filename}', + Route::post('/restore/{filename}', [SettingsController::class, 'postRestore'] )->name('settings.backups.restore'); - Route::post('/upload', + Route::post('/upload', [SettingsController::class, 'postUploadBackup'] )->name('settings.backups.upload'); @@ -415,7 +416,7 @@ Route::group(['prefix' => 'account', 'middleware' => ['auth']], function () { 'display-sig/{filename}', [ProfileController::class, 'displaySig'] )->name('profile.signature.view'); - + Route::get( 'stored-eula-file/{filename}', [ProfileController::class, 'getStoredEula'] @@ -604,23 +605,24 @@ Route::get( Route::group(['prefix' => 'setup', 'middleware' => 'web'], function () { Route::get( 'user', - [SettingsController::class, 'getSetupUser'] + [SetupController::class, 'getSetupUser'] )->name('setup.user'); Route::post( 'user', - [SettingsController::class, 'postSaveFirstAdmin'] + [SetupController::class, 'postSaveFirstAdmin'] )->name('setup.user.save'); - Route::get( + Route::post( 'migrate', - [SettingsController::class, 'getSetupMigrate'] + [SetupController::class, 'SetupMigrate'] )->name('setup.migrate'); + Route::get( 'done', - [SettingsController::class, 'getSetupDone'] + [SetupController::class, 'getSetupDone'] )->name('setup.done'); Route::get( @@ -630,7 +632,7 @@ Route::group(['prefix' => 'setup', 'middleware' => 'web'], function () { Route::get( '/', - [SettingsController::class, 'getSetupIndex'] + [SetupController::class, 'getSetupIndex'] )->name('setup'); }); diff --git a/tests/Feature/Setup/Ui/IndexSetupTest.php b/tests/Feature/Setup/Ui/IndexSetupTest.php new file mode 100644 index 0000000000..ee924eae54 --- /dev/null +++ b/tests/Feature/Setup/Ui/IndexSetupTest.php @@ -0,0 +1,85 @@ +get(route('setup')) + ->assertOk(); + } + + public function testPageRedirectsIfNoRecordsFound() + { + $this->assertDatabaseEmpty('users'); + + $this->get(route('home')) + ->assertStatus(302) + ->assertRedirectToRoute('setup'); + } + + public function testPageRedirectsIfRecordsFound() { + $this->actingAs(User::factory()->superuser()->create()) + ->get(route('setup')) + ->assertStatus(302) + ->assertRedirectToRoute('home'); + } + + public function testMigrationPageRenders() { + + $this->assertDatabaseEmpty('users'); + + $this->post(route('setup.migrate')) + ->assertOk(); + + } + + public function testCreateFirstUserPageRenders() { + + $this->assertDatabaseEmpty('users'); + + $this->get(route('setup.user')) + ->assertOk(); + + } + + public function testCreateFirstUserValidation() { + + $this->assertDatabaseEmpty('users'); + + $response = $this->post(route('setup.user.save')) + ->assertStatus(302); + + $this->followRedirects($response)->assertSee('error'); + $this->assertDatabaseCount('users', 0); + + } + + public function testCreateFirstUserSaved() { + + $this->assertDatabaseEmpty('users'); + + $this->post(route('setup.user.save'), + [ + 'site_name' => 'Snipe-IT', + 'first_name' => 'First', + 'last_name' => 'Admin', + 'username' => 'AwesomeAdmin', + 'password' => '0834529!!*423', + 'password_confirmation' => '0834529!!*423', + 'email_domain' => 'example.org', + ]) + ->assertRedirectToRoute('setup.done') + ->assertStatus(302) + ->assertSessionHas('success'); + + + + $this->assertDatabaseCount('users', 1); + + } +} diff --git a/tests/Support/Settings.php b/tests/Support/Settings.php index 4ea8ddb8aa..f675c5438a 100644 --- a/tests/Support/Settings.php +++ b/tests/Support/Settings.php @@ -19,7 +19,7 @@ class Settings return new self(); } - public function enableAlertEmail(string $email = 'notifications@afcrichmond.com'): Settings + public function enableAlertEmail(string $email = 'notifications@example.org'): Settings { return $this->update([ 'alert_email' => $email, @@ -46,7 +46,7 @@ class Settings ]); } - public function enableAdminCC(string $email = 'cc@example.co'): Settings + public function enableAdminCC(string $email = 'cc@example.org'): Settings { return $this->update([ 'admin_cc_email' => $email,
@if ($start_settings['gd']) - GD is installed. Go you! +

GD is installed. Go you!

@else - The GD library isn't installed. While this won't prevent the system from working, you won't be able to generate labels or upload images. +

The GD library isn't installed. While this won't prevent the system from working, you won't be able to generate labels or upload images.

@endif
Email - - Send Test + - - - -
-
-
-
-

This will attempt to send a test mail to {{ config('mail.from.address') }}.

-
+

This will attempt to send a test mail to {{ config('mail.from.address') }}.

+ Send Test +