diff --git a/.env.example b/.env.example index 1bf4d360..3a416259 100644 --- a/.env.example +++ b/.env.example @@ -10,7 +10,7 @@ LOG_CHANNEL=daily SCOUT_DRIVER=tntsearch SCOUT_QUEUE=true -FILESYSTEM_DRIVER= +FILESYSTEM_DRIVER=local CHUNK_SIZE=128 DB_CONNECTION=mysql diff --git a/README.md b/README.md index 8a2f7049..41c7564e 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,3 @@ -[![Frontend Build](https://github.com/MakingCG/vuefilemanager/actions/workflows/build.yml/badge.svg)](https://github.com/MakingCG/vuefilemanager/actions/workflows/build.yml) -[![Unit Testing](https://github.com/MakingCG/vuefilemanager/actions/workflows/unit-testing.yml/badge.svg)](https://github.com/MakingCG/vuefilemanager/actions/workflows/unit-testing.yml) ![logo](https://vuefilemanager.com/assets/images/vuefilemanager-horizontal-logo.svg) # Private Cloud Storage Build on Laravel & Vue.js @@ -33,7 +31,7 @@ **For running app make sure you have installed:** -- PHP >= 7.3 version +- PHP >= 8.0.2 version - MySQL 5.6+ - Nginx or Apache @@ -176,49 +174,15 @@ These instructions is applicable for all updates. Please follow this step: - Just rewrite all project files with new excluded `/.env` file and `/storage` folder. These items must be preserved! - -# Payments -VueFileManager is packed with **Stripe** payment options. To configure Stripe, you will be asked in Setup Wizard to set up. Or, if you skip this installation process, you will find stripe set up in you admin `Dashboard / Settings / Payments`. - -## Manage Failed Payments -VueFileManager manage failed payments with additional email notification. But, there is more you can do for better User Experience. There is some additionals option in Stripe, look on [prevent failed payments](https://dashboard.stripe.com/settings/billing/automatic). - -## Tax Rates -You are able to manage tax rates. When adding a new tax rate, if no Region is specified, the tax rate will apply to everyone. Add a [ISO 3166-1 alpha-2 country code](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2#Officially_assigned_code_elements) to the Region field if you wish to apply taxes per country. - -Just log in to your stripe dashboard, and you will find taxes under `Dashboard / Products / Tax Rates`. - # Developers ## Running development environment on your localhost -When you download repository from GitHub, you have to rename your `.env.example` file to `.env`. Then run command below in your terminal to install vendors. Composer is required. -``` -composer install -``` - -Set your `APP_ENV` to local mode, in default, it's in production mode. -``` -APP_ENV=local -``` - -Also, to debug application, set `APP_DEBUG` on true: -``` -APP_DEBUG=true -``` - To start server on your localhost, run command below. Then go to your generated localhost URL by terminal, and follow Setup Wizard steps to configure VueFileManager. ``` php artisan serve ``` -After successfully installation via Setup Wizard, stop your artisan server, clear config cache and run your artisan server again: -``` -php artisan config:clear -php artisan serve -``` -*After any change in your .env you have to restart your artisan server to reload your config cache.* - -To develop your Vue front-end, you have to install npm modules by this command: +For developing Vue front-end, you have to install npm modules by this command: ``` npm install ``` diff --git a/resources/js/store/modules/lists.js b/resources/js/store/modules/lists.js index f6be80c5..a6023295 100644 --- a/resources/js/store/modules/lists.js +++ b/resources/js/store/modules/lists.js @@ -1,6 +1,38 @@ import i18n from '../../i18n' const defaultState = { + mailEncryptionList: [ + { + label: 'TLS', + value: 'tls', + }, + { + label: 'SSL', + value: 'ssl', + }, + ], + mailDriverList: [ + { + label: 'SMTP', + value: 'smtp', + }, + { + label: 'Mailgun', + value: 'mailgun', + }, + { + label: 'SES', + value: 'ses', + }, + { + label: 'Postmark', + value: 'postmark', + }, + { + label: 'Log', + value: 'log', + }, + ], transactionColumns: [ { label: i18n.t('Note'), @@ -1023,9 +1055,11 @@ const defaultState = { } const getters = { + mailEncryptionList: (state) => state.mailEncryptionList, transactionColumns: (state) => state.transactionColumns, subscriptionTypes: (state) => state.subscriptionTypes, teamPermissions: (state) => state.teamPermissions, + mailDriverList: (state) => state.mailDriverList, expirationList: (state) => state.expirationList, currencyList: (state) => state.currencyList, intervalList: (state) => state.intervalList, diff --git a/resources/js/views/Admin/AppSettings/AppSettingsTabs/Email.vue b/resources/js/views/Admin/AppSettings/AppSettingsTabs/Email.vue index f8f0b09b..4b6242b5 100644 --- a/resources/js/views/Admin/AppSettings/AppSettingsTabs/Email.vue +++ b/resources/js/views/Admin/AppSettings/AppSettingsTabs/Email.vue @@ -2,70 +2,100 @@ {{ $t('admin_settings.email.section_email') }} - -

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + + + + + + + + + + +
+ +
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
+ + {{ $t('admin_settings.email.save_button') }}
@@ -86,6 +116,7 @@ import InfoBox from '../../../../components/Others/Forms/InfoBox' import { required } from 'vee-validate/dist/rules' import { events } from '../../../../bus' import axios from 'axios' +import {mapGetters} from "vuex"; export default { name: 'AppAppearance', @@ -103,59 +134,78 @@ export default { PageTab, InfoBox, }, + computed: { + ...mapGetters([ + 'mailEncryptionList', + 'mailDriverList', + ]), + }, data() { return { isLoading: false, isSendingRequest: false, - encryptionList: [ - { - label: 'TLS', - value: 'tls', - }, - { - label: 'SSL', - value: 'ssl', - }, - ], - mail: { - driver: '', - host: '', - port: '', - username: '', - password: '', - encryption: '', - }, + mailDriver: undefined, + ses: { + access_key: undefined, + secret_access_key: undefined, + default_region: undefined, + session_token: undefined, + }, + smtp: { + host: undefined, + port: undefined, + username: undefined, + password: undefined, + encryption: undefined, + }, + mailgun: { + domain: undefined, + secret: undefined, + endpoint: undefined, + }, + postmark: { + token: undefined, + }, } }, methods: { async EmailSetupSubmit() { - // Validate fields - const isValid = await this.$refs.EmailSetup.validate() - if (!isValid) return + // Validate fields + const isValid = await this.$refs.EmailSetup.validate() - // Start loading - this.isSendingRequest = true + if (!isValid) return - // Send request to get verify account - axios - .post('/api/admin/settings/email', this.mail) - .then(() => { - events.$emit('toaster', { - type: 'success', - message: this.$t('toaster.email_set'), - }) - }) - .catch(() => { - events.$emit('alert:open', { - title: this.$t('popup_error.title'), - message: this.$t('popup_error.message'), - }) - }) - .finally(() => { - // End loading - this.isSendingRequest = false - }) + // Start loading + this.isSendingRequest = true + + // Send request to get verify account + axios + .post('/api/admin/settings/email', { + environment: this.environment, + storage: this.storage, + mailDriver: this.mailDriver, + smtp: this.smtp, + mailgun: this.mailgun, + ses: this.ses, + postmark: this.postmark, + }) + .then(() => { + events.$emit('toaster', { + type: 'success', + message: this.$t('toaster.email_set'), + }) + }) + .catch((error) => { + events.$emit('alert:open', { + title: this.$t('popup_error.title'), + message: this.$t('popup_error.message'), + }) + + }) + .finally(() => { + this.isSendingRequest = false + }) }, }, } diff --git a/resources/js/views/SetupWizard/EnvironmentSetup.vue b/resources/js/views/SetupWizard/EnvironmentSetup.vue index 4b328bfa..aa402bfa 100644 --- a/resources/js/views/SetupWizard/EnvironmentSetup.vue +++ b/resources/js/views/SetupWizard/EnvironmentSetup.vue @@ -87,7 +87,7 @@ - + @@ -180,6 +180,7 @@ import {SettingsIcon} from 'vue-feather-icons' import Headline from '../Auth/Headline' import {required} from 'vee-validate/dist/rules' import axios from 'axios' +import {mapGetters} from "vuex"; export default { name: 'EnvironmentSetup', @@ -212,6 +213,10 @@ export default { }, }, computed: { + ...mapGetters([ + 'mailEncryptionList', + 'mailDriverList', + ]), regionList() { return { storj: this.storjRegions, @@ -468,38 +473,6 @@ export default { value: 'oss', }, ], - encryptionList: [ - { - label: 'TLS', - value: 'tls', - }, - { - label: 'SSL', - value: 'ssl', - }, - ], - mailDriverList: [ - { - label: 'SMTP', - value: 'smtp', - }, - { - label: 'Mailgun', - value: 'mailgun', - }, - { - label: 'SES', - value: 'ses', - }, - { - label: 'Postmark', - value: 'postmark', - }, - { - label: 'Log', - value: 'log', - }, - ], storage: { driver: 'local', key: undefined, diff --git a/routes/admin.php b/routes/admin.php index e6b7b806..f125132c 100644 --- a/routes/admin.php +++ b/routes/admin.php @@ -2,7 +2,7 @@ use Domain\Admin\Controllers\Users\UserController; use Domain\Pages\Controllers\AdminPagesController; -use Domain\Settings\Controllers\SetEmailController; +use Domain\Settings\Controllers\StoreEmailCredentialsController; use Domain\Settings\Controllers\FlushCacheController; use Domain\Localization\Controllers\LanguageController; use Domain\Admin\Controllers\Users\DeleteUserController; @@ -48,7 +48,7 @@ Route::group(['prefix' => 'settings'], function () { Route::get('/', GetSettingsValueController::class); Route::get('/flush-cache', FlushCacheController::class); - Route::post('/email', SetEmailController::class); + Route::post('/email', StoreEmailCredentialsController::class); Route::post('/payment-service', StorePaymentServiceCredentialsController::class); Route::post('/social-service', StoreSocialServiceCredentialsController::class); diff --git a/src/App/Console/Commands/SetupDevEnvironment.php b/src/App/Console/Commands/SetupDevEnvironment.php index 672082ef..941a5b47 100644 --- a/src/App/Console/Commands/SetupDevEnvironment.php +++ b/src/App/Console/Commands/SetupDevEnvironment.php @@ -57,7 +57,7 @@ class SetupDevEnvironment extends Command $this->info('Storing default settings and content...'); ($this->seedDefaultPages)(); - ($this->seedDefaultSettings)($this->argument('type')); + ($this->seedDefaultSettings)($this->argument('license')); ($this->seedDefaultLanguage)(); $this->store_default_settings(); @@ -82,6 +82,8 @@ class SetupDevEnvironment extends Command '--stop-when-empty' => true, ]); + $this->warn('Please make sure your current host/domain where you are running app is included in your .env SANCTUM_STATEFUL_DOMAINS variable.'); + $this->info('Everything is done, congratulations! 🥳🥳🥳'); } @@ -1026,7 +1028,7 @@ class SetupDevEnvironment extends Command ], [ 'name' => 'license', - 'value' => $this->argument('type'), + 'value' => $this->argument('license'), ], [ 'name' => 'purchase_code', diff --git a/src/App/Console/Commands/SetupProdEnvironment.php b/src/App/Console/Commands/SetupProdEnvironment.php index f94bddb1..c2ffadeb 100644 --- a/src/App/Console/Commands/SetupProdEnvironment.php +++ b/src/App/Console/Commands/SetupProdEnvironment.php @@ -8,9 +8,12 @@ use Domain\Pages\Actions\SeedDefaultPagesAction; use Domain\Settings\Actions\SeedDefaultSettingsAction; use Domain\Localization\Actions\SeedDefaultLanguageAction; use Domain\SetupWizard\Actions\CreateDiskDirectoriesAction; +use Illuminate\Foundation\Testing\WithFaker; class SetupProdEnvironment extends Command { + use WithFaker; + /** * The name and signature of the console command. */ @@ -30,6 +33,7 @@ class SetupProdEnvironment extends Command private SeedDefaultPagesAction $seedDefaultPages, ) { parent::__construct(); + $this->setUpFaker(); } /** @@ -51,7 +55,7 @@ class SetupProdEnvironment extends Command $this->store_default_settings(); ($this->seedDefaultPages)(); - ($this->seedDefaultSettings)($this->argument('type')); + ($this->seedDefaultSettings)($this->argument('license')); ($this->seedDefaultLanguage)(); $this->info('Creating default admin...'); @@ -60,6 +64,8 @@ class SetupProdEnvironment extends Command $this->info('Clearing application cache...'); $this->clear_cache(); + $this->warn('Please make sure your current host/domain where you are running app is included in your .env SANCTUM_STATEFUL_DOMAINS variable.'); + $this->info('Everything is done, congratulations! 🥳🥳🥳'); } @@ -136,7 +142,7 @@ class SetupProdEnvironment extends Command ], [ 'name' => 'license', - 'value' => $this->argument('type'), + 'value' => $this->argument('license'), ], [ 'name' => 'purchase_code', @@ -197,7 +203,15 @@ class SetupProdEnvironment extends Command $user ->settings() ->create([ - 'name' => 'Admin', + 'first_name' => 'Jane', + 'last_name' => 'Doe', + 'address' => $this->faker->address, + 'state' => $this->faker->state, + 'city' => $this->faker->city, + 'postal_code' => $this->faker->postcode, + 'country' => $this->faker->randomElement(['SK', 'CZ', 'DE', 'FR']), + 'phone_number' => $this->faker->phoneNumber, + 'timezone' => $this->faker->randomElement(['+1.0', '+2.0', '+3.0']), ]); // Show user credentials @@ -218,6 +232,12 @@ class SetupProdEnvironment extends Command $this->call('key:generate', [ '--force' => true, ]); + + $currentHost = request()->getHost() . ',' . request()->getHost() . ':' . request()->getPort(); + + setEnvironmentValue([ + 'SANCTUM_STATEFUL_DOMAINS' => "localhost,localhost:8000,127.0.0.1,127.0.0.1:8000,::1,$currentHost", + ]); } /** diff --git a/src/Domain/Settings/Controllers/SetEmailController.php b/src/Domain/Settings/Controllers/SetEmailController.php deleted file mode 100644 index e10654b0..00000000 --- a/src/Domain/Settings/Controllers/SetEmailController.php +++ /dev/null @@ -1,36 +0,0 @@ -runningUnitTests()) { - setEnvironmentValue([ - 'MAIL_DRIVER' => $request->input('driver'), - 'MAIL_HOST' => $request->input('host'), - 'MAIL_PORT' => $request->input('port'), - 'MAIL_USERNAME' => $request->input('username'), - 'MAIL_PASSWORD' => $request->input('password'), - 'MAIL_ENCRYPTION' => $request->input('encryption'), - ]); - - // Clear config cache - Artisan::call('config:clear'); - Artisan::call('config:cache'); - } - - return response('Done', 204); - } -} diff --git a/src/Domain/Settings/Controllers/StoreEmailCredentialsController.php b/src/Domain/Settings/Controllers/StoreEmailCredentialsController.php new file mode 100644 index 00000000..ce4429f9 --- /dev/null +++ b/src/Domain/Settings/Controllers/StoreEmailCredentialsController.php @@ -0,0 +1,65 @@ +runningUnitTests()) { + + $mail = [ + 'log' => [ + 'MAIL_DRIVER' => 'log', + ], + 'postmark' => [ + 'MAIL_DRIVER' => 'postmark', + 'POSTMARK_TOKEN' => $request->input('postmark.token'), + ], + 'smtp' => [ + 'MAIL_DRIVER' => 'smtp', + 'MAIL_HOST' => $request->input('smtp.host'), + 'MAIL_PORT' => $request->input('smtp.port'), + 'MAIL_USERNAME' => $request->input('smtp.username'), + 'MAIL_PASSWORD' => $request->input('smtp.password'), + 'MAIL_ENCRYPTION' => $request->input('smtp.encryption'), + ], + 'ses' => [ + 'MAIL_DRIVER' => 'ses', + 'AWS_ACCESS_KEY_ID' => $request->input('ses.access_key'), + 'AWS_SECRET_ACCESS_KEY' => $request->input('ses.secret_access_key'), + 'AWS_DEFAULT_REGION' => $request->input('ses.default_region'), + 'AWS_SESSION_TOKEN' => $request->input('ses.session_token'), + ], + 'mailgun' => [ + 'MAIL_DRIVER' => 'mailgun', + 'MAILGUN_DOMAIN' => $request->input('mailgun.domain'), + 'MAILGUN_SECRET' => $request->input('mailgun.secret'), + 'MAILGUN_ENDPOINT' => $request->input('mailgun.endpoint'), + ], + ]; + + // Store credentials for mail + setEnvironmentValue( + $mail[$request->input('mailDriver')] + ); + + // Clear config cache + Artisan::call('config:clear'); + Artisan::call('config:cache'); + } + + return response('Done', 204); + } +} diff --git a/src/Domain/Settings/Requests/StoreEmailCredentialsRequest.php b/src/Domain/Settings/Requests/StoreEmailCredentialsRequest.php new file mode 100644 index 00000000..1d9e81e6 --- /dev/null +++ b/src/Domain/Settings/Requests/StoreEmailCredentialsRequest.php @@ -0,0 +1,33 @@ + 'required|string', + 'smtp' => 'sometimes|array', + 'ses' => 'sometimes|array', + 'mailgun' => 'sometimes|array', + 'postmark' => 'sometimes|array', + ]; + } +} diff --git a/src/Domain/SetupWizard/Controllers/StoreEnvironmentSettingsController.php b/src/Domain/SetupWizard/Controllers/StoreEnvironmentSettingsController.php index fdf50c2b..22e97982 100644 --- a/src/Domain/SetupWizard/Controllers/StoreEnvironmentSettingsController.php +++ b/src/Domain/SetupWizard/Controllers/StoreEnvironmentSettingsController.php @@ -44,6 +44,7 @@ class StoreEnvironmentSettingsController extends Controller 'MAIL_DRIVER' => 'log', ], 'postmark' => [ + 'MAIL_DRIVER' => 'postmark', 'POSTMARK_TOKEN' => $request->input('postmark.token'), ], 'smtp' => [ diff --git a/src/Domain/SetupWizard/Requests/StoreEnvironmentSetupRequest.php b/src/Domain/SetupWizard/Requests/StoreEnvironmentSetupRequest.php index 615fd7be..213e1fc8 100644 --- a/src/Domain/SetupWizard/Requests/StoreEnvironmentSetupRequest.php +++ b/src/Domain/SetupWizard/Requests/StoreEnvironmentSetupRequest.php @@ -33,9 +33,10 @@ class StoreEnvironmentSetupRequest extends FormRequest 'storage.region' => 'sometimes|nullable|string', 'storage.bucket' => 'sometimes|nullable|string', 'mailDriver' => 'required|string', - 'mail' => 'sometimes|array', + 'smtp' => 'sometimes|array', 'ses' => 'sometimes|array', 'mailgun' => 'sometimes|array', + 'postmark' => 'sometimes|array', ]; } }