set broadcasting in admin and setup wizard

This commit is contained in:
Čarodej
2022-03-16 09:37:17 +01:00
parent 4bab179e17
commit 9d955799d3
16 changed files with 666 additions and 161 deletions

View File

@@ -89,6 +89,7 @@ PUSHER_APP_KEY=local
PUSHER_APP_SECRET=local
PUSHER_APP_CLUSTER=mt1
PUSHER_APP_HOST=
PUSHER_APP_PORT=
IS_ADMIN_VUEFILEMANAGER_BAR=true
IS_SETUP_WIZARD_DEMO=false

View File

@@ -37,7 +37,7 @@ return [
'cluster' => env('PUSHER_APP_CLUSTER'),
'encrypted' => true,
'host' => env('PUSHER_APP_HOST'),
'port' => 8002,
'port' => env('PUSHER_APP_PORT'),
'scheme' => env('APP_ENV') === 'local' ? 'http' : 'https',
],
],

View File

@@ -7,7 +7,7 @@ return [
* Set a custom dashboard configuration
*/
'dashboard' => [
'port' => env('LARAVEL_WEBSOCKETS_PORT', 6001),
'port' => env('PUSHER_APP_PORT', 6001),
],
/*
@@ -29,7 +29,7 @@ return [
'path' => env('PUSHER_APP_PATH'),
'capacity' => null,
'enable_client_messages' => false,
'enable_statistics' => true,
'enable_statistics' => false,
],
],
@@ -57,7 +57,7 @@ return [
/*
* This path will be used to register the necessary routes for the package.
*/
'path' => 'laravel-websockets',
'path' => 'websockets',
/*
* Dashboard Routes Middleware

View File

@@ -1,75 +1,75 @@
{
"/js/main.js": "/js/main.js",
"/chunks/request.js": "/chunks/request.js?id=1bff15b826caa049",
"/chunks/request-upload.js": "/chunks/request-upload.js?id=fc440ef3b84f69f2",
"/chunks/setup-wizard.js": "/chunks/setup-wizard.js?id=3c2fc454c3fce8d2",
"/chunks/status-check.js": "/chunks/status-check.js?id=f5560c0c419368d4",
"/chunks/purchase-code.js": "/chunks/purchase-code.js?id=a9fef88d23daf0a4",
"/chunks/database.js": "/chunks/database.js?id=ac7bf12a4a759a68",
"/chunks/environment-setup.js": "/chunks/environment-setup.js?id=18f6c3b6bb32f565",
"/chunks/app-setup.js": "/chunks/app-setup.js?id=ba3ab076bce13741",
"/chunks/admin-account.js": "/chunks/admin-account.js?id=211e9c4b9cec9c1d",
"/chunks/shared.js": "/chunks/shared.js?id=5f6ef21f54e57a39",
"/chunks/shared/browser.js": "/chunks/shared/browser.js?id=768f223f231bdb8e",
"/chunks/shared/single-file.js": "/chunks/shared/single-file.js?id=03c597cddf8ea6e8",
"/chunks/shared/authenticate.js": "/chunks/shared/authenticate.js?id=17c2e203a48cc0ac",
"/chunks/not-found.js": "/chunks/not-found.js?id=f66d6819e5335ad7",
"/chunks/temporary-unavailable.js": "/chunks/temporary-unavailable.js?id=ba49ed84eaeb6e76",
"/chunks/admin.js": "/chunks/admin.js?id=af0759535f4ba6b1",
"/chunks/dashboard.js": "/chunks/dashboard.js?id=7d45c0ac0a205300",
"/chunks/invoices.js": "/chunks/invoices.js?id=1344281edac589dd",
"/chunks/subscriptions.js": "/chunks/subscriptions.js?id=5eb4e2a4cdd4cee7",
"/chunks/pages.js": "/chunks/pages.js?id=41dd38fa40aed8de",
"/chunks/page-edit.js": "/chunks/page-edit.js?id=4f54f01640f91ea4",
"/chunks/plans.js": "/chunks/plans.js?id=dd4507f0ac4e8355",
"/chunks/users.js": "/chunks/users.js?id=85e64bb0dde749ae",
"/chunks/user-create.js": "/chunks/user-create.js?id=94cb6de3fa97532f",
"/chunks/plan-create/fixed.js": "/chunks/plan-create/fixed.js?id=233b503c533785b6",
"/chunks/plan-create/metered.js": "/chunks/plan-create/metered.js?id=545c00fed7a4afc6",
"/chunks/user.js": "/chunks/user.js?id=be6451917a05f8bb",
"/chunks/user-detail.js": "/chunks/user-detail.js?id=d24d758ff91cabaa",
"/chunks/user-storage.js": "/chunks/user-storage.js?id=558bcacad7f65e01",
"/chunks/user-subscription.js": "/chunks/user-subscription.js?id=1c86ce0edbb859df",
"/chunks/user-password.js": "/chunks/user-password.js?id=204e36cbf11279ab",
"/chunks/user-delete.js": "/chunks/user-delete.js?id=bbf64bfbcc6eb5f9",
"/chunks/plan.js": "/chunks/plan.js?id=2444730c1a0a42fc",
"/chunks/plan-subscribers.js": "/chunks/plan-subscribers.js?id=f38b09679bd4aee8",
"/chunks/plan-settings.js": "/chunks/plan-settings.js?id=887502be9ee6ef81",
"/chunks/plan-delete.js": "/chunks/plan-delete.js?id=f11556bf815870ba",
"/chunks/payments.js": "/chunks/payments.js?id=5ea275fedd8d638a",
"/chunks/payments/billings.js": "/chunks/payments/billings.js?id=d81a724698921629",
"/chunks/payments/settings.js": "/chunks/payments/settings.js?id=74ca6b64360e3a90",
"/chunks/app-settings.js": "/chunks/app-settings.js?id=b0ca7cdad56e46fd",
"/chunks/app-appearance.js": "/chunks/app-appearance.js?id=dc3f788ada12db0e",
"/chunks/app-index.js": "/chunks/app-index.js?id=2be003c6977e905c",
"/chunks/app-environment.js": "/chunks/app-environment.js?id=d8ccf7060f264481",
"/chunks/app-others.js": "/chunks/app-others.js?id=2d437d95f3823ded",
"/chunks/app-sign-in-out.js": "/chunks/app-sign-in-out.js?id=72cec1f30f1fd569",
"/chunks/app-adsense.js": "/chunks/app-adsense.js?id=30a7d6424225bcd0",
"/chunks/app-server.js": "/chunks/app-server.js?id=442ad4f53cfa9acf",
"/chunks/app-language.js": "/chunks/app-language.js?id=b2db52bfd512e402",
"/chunks/homepage.js": "/chunks/homepage.js?id=a124f28e2fc0989a",
"/chunks/dynamic-page.js": "/chunks/dynamic-page.js?id=bbd1a3b0be7dbeee",
"/chunks/contact-us.js": "/chunks/contact-us.js?id=aeaa4a6b4cb54077",
"/chunks/successfully-email-verified.js": "/chunks/successfully-email-verified.js?id=8b408a43fd142f52",
"/chunks/successfully-email-send.js": "/chunks/successfully-email-send.js?id=a56734c5e2dec0f7",
"/chunks/sign-in.js": "/chunks/sign-in.js?id=54ed293fa5567b44",
"/chunks/sign-up.js": "/chunks/sign-up.js?id=e3248c3046a7678d",
"/chunks/forgotten-password.js": "/chunks/forgotten-password.js?id=30bd34966d5984c1",
"/chunks/create-new-password.js": "/chunks/create-new-password.js?id=621acbfefc5a37a2",
"/chunks/settings.js": "/chunks/settings.js?id=f30383f4be36162c",
"/chunks/profile.js": "/chunks/profile.js?id=6f41d5db05622afd",
"/chunks/settings-password.js": "/chunks/settings-password.js?id=5aed9d38b48443d7",
"/chunks/settings-storage.js": "/chunks/settings-storage.js?id=1ef8a566ec05ea66",
"/chunks/billing.js": "/chunks/billing.js?id=e0068be5f76f4e11",
"/chunks/platform.js": "/chunks/platform.js?id=579d6f8b1d4fd427",
"/chunks/files.js": "/chunks/files.js?id=2fca4d5bf8d76f77",
"/chunks/recent-uploads.js": "/chunks/recent-uploads.js?id=826d730863ad5007",
"/chunks/my-shared-items.js": "/chunks/my-shared-items.js?id=bee7fb3659324c13",
"/chunks/trash.js": "/chunks/trash.js?id=b05f60f478c2b0fe",
"/chunks/team-folders.js": "/chunks/team-folders.js?id=ad342ee2c293e040",
"/chunks/shared-with-me.js": "/chunks/shared-with-me.js?id=1b901489d1d168ab",
"/chunks/invitation.js": "/chunks/invitation.js?id=f95f29e6e6632330",
"/chunks/request.js": "/chunks/request.js?id=6e899824be266ea6",
"/chunks/request-upload.js": "/chunks/request-upload.js?id=e7b753c68007d5d1",
"/chunks/setup-wizard.js": "/chunks/setup-wizard.js?id=19a0784e59d768ec",
"/chunks/status-check.js": "/chunks/status-check.js?id=336de73834cc9a29",
"/chunks/purchase-code.js": "/chunks/purchase-code.js?id=df5bd89528649783",
"/chunks/database.js": "/chunks/database.js?id=ba3140027421b977",
"/chunks/environment-setup.js": "/chunks/environment-setup.js?id=fc3886e258b9a9b9",
"/chunks/app-setup.js": "/chunks/app-setup.js?id=7bae302e249c73a1",
"/chunks/admin-account.js": "/chunks/admin-account.js?id=309dc20e668952e6",
"/chunks/shared.js": "/chunks/shared.js?id=e68646d339b36632",
"/chunks/shared/browser.js": "/chunks/shared/browser.js?id=52851612b04dba61",
"/chunks/shared/single-file.js": "/chunks/shared/single-file.js?id=4bd19aefcb3bdfdd",
"/chunks/shared/authenticate.js": "/chunks/shared/authenticate.js?id=c303bb3ce8a22918",
"/chunks/not-found.js": "/chunks/not-found.js?id=5fbc874846003a91",
"/chunks/temporary-unavailable.js": "/chunks/temporary-unavailable.js?id=9c283755ffea5e90",
"/chunks/admin.js": "/chunks/admin.js?id=c3eb2a10ca6f09b8",
"/chunks/dashboard.js": "/chunks/dashboard.js?id=3cb0b23a8ab78cbb",
"/chunks/invoices.js": "/chunks/invoices.js?id=f89964a5a55ace45",
"/chunks/subscriptions.js": "/chunks/subscriptions.js?id=62582c26b6288d7d",
"/chunks/pages.js": "/chunks/pages.js?id=d7219aff1586ef7a",
"/chunks/page-edit.js": "/chunks/page-edit.js?id=8a6b001219a08faf",
"/chunks/plans.js": "/chunks/plans.js?id=704f996bd6e6c651",
"/chunks/users.js": "/chunks/users.js?id=f3c592b251f7d183",
"/chunks/user-create.js": "/chunks/user-create.js?id=617e9bf3df1739b2",
"/chunks/plan-create/fixed.js": "/chunks/plan-create/fixed.js?id=b557039c3b07913a",
"/chunks/plan-create/metered.js": "/chunks/plan-create/metered.js?id=8db8eabf6b39775b",
"/chunks/user.js": "/chunks/user.js?id=7e567c0cb7f641d6",
"/chunks/user-detail.js": "/chunks/user-detail.js?id=6c169888720ad92a",
"/chunks/user-storage.js": "/chunks/user-storage.js?id=f66071eb1b65c082",
"/chunks/user-subscription.js": "/chunks/user-subscription.js?id=f033931911b07f5c",
"/chunks/user-password.js": "/chunks/user-password.js?id=6d23f552e9d52c49",
"/chunks/user-delete.js": "/chunks/user-delete.js?id=82b5180a1d9e1217",
"/chunks/plan.js": "/chunks/plan.js?id=37a04161ac1973ad",
"/chunks/plan-subscribers.js": "/chunks/plan-subscribers.js?id=2cc70b67d00bbda1",
"/chunks/plan-settings.js": "/chunks/plan-settings.js?id=1679d4320a70fc13",
"/chunks/plan-delete.js": "/chunks/plan-delete.js?id=1a03842f88224cbd",
"/chunks/payments.js": "/chunks/payments.js?id=2a6dba57de536b0d",
"/chunks/payments/billings.js": "/chunks/payments/billings.js?id=a434d9363a14beab",
"/chunks/payments/settings.js": "/chunks/payments/settings.js?id=bf165e8846059cad",
"/chunks/app-settings.js": "/chunks/app-settings.js?id=ac94675bfea2ac48",
"/chunks/app-appearance.js": "/chunks/app-appearance.js?id=e388c80adec307d7",
"/chunks/app-index.js": "/chunks/app-index.js?id=6befbefd7ebeb16a",
"/chunks/app-environment.js": "/chunks/app-environment.js?id=d5ebc63ff754aa33",
"/chunks/app-others.js": "/chunks/app-others.js?id=0cc43e1d502eec99",
"/chunks/app-sign-in-out.js": "/chunks/app-sign-in-out.js?id=d3ed0a81743ac3ba",
"/chunks/app-adsense.js": "/chunks/app-adsense.js?id=4ee8de4ac0dae19e",
"/chunks/app-server.js": "/chunks/app-server.js?id=4959028c9adbedfa",
"/chunks/app-language.js": "/chunks/app-language.js?id=83a53ba4d233ae46",
"/chunks/homepage.js": "/chunks/homepage.js?id=3a8a009996ff94d0",
"/chunks/dynamic-page.js": "/chunks/dynamic-page.js?id=0585ee757e04fe8d",
"/chunks/contact-us.js": "/chunks/contact-us.js?id=1b8ef1d52ded4eff",
"/chunks/successfully-email-verified.js": "/chunks/successfully-email-verified.js?id=887ca001d1542b96",
"/chunks/successfully-email-send.js": "/chunks/successfully-email-send.js?id=f4562229776d9f56",
"/chunks/sign-in.js": "/chunks/sign-in.js?id=bbed1e72f0086331",
"/chunks/sign-up.js": "/chunks/sign-up.js?id=f23b52bc6ff0107b",
"/chunks/forgotten-password.js": "/chunks/forgotten-password.js?id=63bc2a81117cee2f",
"/chunks/create-new-password.js": "/chunks/create-new-password.js?id=b7d1b17596c771c3",
"/chunks/settings.js": "/chunks/settings.js?id=10aae65b59430310",
"/chunks/profile.js": "/chunks/profile.js?id=baa99177b1a788a2",
"/chunks/settings-password.js": "/chunks/settings-password.js?id=29034c929a287e2a",
"/chunks/settings-storage.js": "/chunks/settings-storage.js?id=80bca2eb75da275d",
"/chunks/billing.js": "/chunks/billing.js?id=9008d99558ed20a5",
"/chunks/platform.js": "/chunks/platform.js?id=2fc77f79e9101e15",
"/chunks/files.js": "/chunks/files.js?id=3900f3a00b9b8240",
"/chunks/recent-uploads.js": "/chunks/recent-uploads.js?id=346215cfda8b1688",
"/chunks/my-shared-items.js": "/chunks/my-shared-items.js?id=68fc784dcea2aabf",
"/chunks/trash.js": "/chunks/trash.js?id=8059bce40717c58a",
"/chunks/team-folders.js": "/chunks/team-folders.js?id=a96b3554276cfbba",
"/chunks/shared-with-me.js": "/chunks/shared-with-me.js?id=52f088dd5be89bd8",
"/chunks/invitation.js": "/chunks/invitation.js?id=21d172e77f12dbbb",
"/css/tailwind.css": "/css/tailwind.css",
"/css/app.css": "/css/app.css"
}

View File

@@ -23,10 +23,11 @@ window.Pusher = require('pusher-js');
if (config.broadcasting) {
window.Echo = new Echo({
broadcaster: 'pusher',
key: 'local',
wsHost: window.location.hostname,
wsPort: 8002,
wssPort: 8002,
cluster: config.broadcastingCluster,
key: config.broadcastingKey,
wsHost: config.broadcastingHost,
wsPort: config.broadcastingPort,
wssPort: config.broadcastingPort,
forceTLS: false,
enabledTransports: ['ws', 'wss'],
});

View File

@@ -17,6 +17,7 @@
<bell-icon v-if="icon === 'bell'" size="22" class="vue-feather text-theme dark-text-theme mr-3" />
<key-icon v-if="icon === 'key'" size="22" class="vue-feather text-theme dark-text-theme mr-3" />
<users-icon v-if="icon === 'users'" size="22" class="vue-feather text-theme dark-text-theme mr-3" />
<wifi-icon v-if="icon === 'wifi'" size="22" class="vue-feather text-theme dark-text-theme mr-3" />
<b class="text-md font-bold dark:text-gray-200 sm:text-lg">
<slot></slot>
</b>
@@ -25,6 +26,7 @@
<script>
import {
WifiIcon,
ListIcon,
MailIcon,
InfoIcon,
@@ -48,6 +50,7 @@ export default {
name: 'FormLabel',
props: ['icon'],
components: {
WifiIcon,
ListIcon,
MailIcon,
InfoIcon,

View File

@@ -10,10 +10,8 @@
<!--Content-->
<div class="flex items-center justify-between">
<div class="flex items-start">
<div>
<check-icon v-if="item.type === 'success'" size="22" class="vue-feather dark:text-green-600 text-green-600" />
<x-icon v-if="item.type === 'danger'" size="22" class="vue-feather dark:text-red-600 text-red-600" />
</div>
<check-icon v-if="item.type === 'success'" size="22" class="vue-feather dark:text-green-600 text-green-600" />
<x-icon v-if="item.type === 'danger'" size="22" class="vue-feather dark:text-red-600 text-red-600" />
<p
class="px-4 font-bold"
@@ -31,12 +29,13 @@
</template>
<script>
import { CheckIcon } from 'vue-feather-icons'
import { CheckIcon, XIcon } from 'vue-feather-icons'
export default {
name: 'Toaster',
components: {
CheckIcon,
XIcon,
},
props: [
'barColor',

View File

@@ -1,5 +1,116 @@
<template>
<PageTab :is-loading="isLoading">
<!--Broadcasting setup-->
<ValidationObserver
@submit.prevent="broadcastSetupSubmit"
ref="broadcastSetup"
v-slot="{ invalid }"
tag="form"
class="card shadow-card"
>
<FormLabel icon="wifi">
{{ $t('Broadcasting') }}
</FormLabel>
<ValidationProvider tag="div" mode="passive" name="Broadcast Driver" rules="required" v-slot="{ errors }">
<AppInputText title="Broadcast Driver" :error="errors[0]">
<SelectInput
v-model="broadcast.driver"
:options="broadcastDrivers"
placeholder="Select your broadcast driver"
:isError="errors[0]"
/>
</AppInputText>
</ValidationProvider>
<div v-if="broadcast.driver === 'native'">
<ValidationProvider tag="div" mode="passive" name="Host" rules="required" v-slot="{ errors }">
<AppInputText title="Hostname or IP" :error="errors[0]">
<input
class="focus-border-theme input-dark"
v-model="broadcast.host"
placeholder="Type your hostname or IP"
type="text"
:class="{ '!border-rose-600': errors[0] }"
/>
</AppInputText>
</ValidationProvider>
<ValidationProvider tag="div" mode="passive" name="Port" rules="required" v-slot="{ errors }">
<AppInputText title="Port" :error="errors[0]">
<input
class="focus-border-theme input-dark"
v-model="broadcast.port"
placeholder="Type your port"
type="text"
:class="{ '!border-rose-600': errors[0] }"
/>
</AppInputText>
</ValidationProvider>
</div>
<div v-if="broadcast.driver === 'pusher'">
<ValidationProvider tag="div" mode="passive" name="App ID" rules="required" v-slot="{ errors }">
<AppInputText title="App ID" :error="errors[0]">
<input
class="focus-border-theme input-dark"
v-model="broadcast.id"
placeholder="Type your app id"
type="text"
:class="{ '!border-rose-600': errors[0] }"
/>
</AppInputText>
</ValidationProvider>
<ValidationProvider tag="div" mode="passive" name="Key" rules="required" v-slot="{ errors }">
<AppInputText title="Key" :error="errors[0]">
<input
class="focus-border-theme input-dark"
v-model="broadcast.key"
placeholder="Paste your key"
type="text"
:class="{ '!border-rose-600': errors[0] }"
/>
</AppInputText>
</ValidationProvider>
<ValidationProvider tag="div" mode="passive" name="Secret" rules="required" v-slot="{ errors }">
<AppInputText title="Secret" :error="errors[0]">
<input
class="focus-border-theme input-dark"
v-model="broadcast.secret"
placeholder="Paste your secret"
type="text"
:class="{ '!border-rose-600': errors[0] }"
/>
</AppInputText>
</ValidationProvider>
<ValidationProvider tag="div" mode="passive" name="Cluster" rules="required" v-slot="{ errors }">
<AppInputText title="Cluster" :error="errors[0]">
<SelectInput
v-model="broadcast.cluster"
:options="pusherClusters"
placeholder="Select your cluster"
:isError="errors[0]"
/>
</AppInputText>
</ValidationProvider>
</div>
<ButtonBase
:loading="isSendingBroadcastForm"
:disabled="isSendingBroadcastForm"
type="submit"
button-style="theme"
class="w-full sm:w-auto"
>
{{ $t('Save Broadcast Settings') }}
</ButtonBase>
</ValidationObserver>
<!--Storage setup-->
<ValidationObserver
@submit.prevent="storageSetupSubmit"
ref="storageSetup"
@@ -117,8 +228,9 @@
</ButtonBase>
</ValidationObserver>
<!--Mail setup-->
<ValidationObserver
@submit.prevent="EmailSetupSubmit"
@submit.prevent="emailSetupSubmit"
ref="EmailSetup"
v-slot="{ invalid }"
tag="form"
@@ -391,7 +503,60 @@ export default {
isLoading: false,
isSendingEmailForm: false,
isSendingStorageForm: false,
isSendingBroadcastForm: false,
mailDriver: undefined,
broadcastDrivers: [
{
label: 'Pusher',
value: 'pusher',
},
{
label: 'VueFileManager Broadcast Server',
value: 'native',
},
{
label: 'None',
value: 'none',
},
],
pusherClusters: [
{
label: 'US East (N. Virginia)',
value: 'mt1',
},
{
label: 'Asia Pacific (Singapore)',
value: 'ap1',
},
{
label: 'Asia Pacific (Mumbai)',
value: 'ap2',
},
{
label: 'US East (Ohio)',
value: 'us2',
},
{
label: 'Asia Pacific (Tokyo)',
value: 'ap3',
},
{
label: 'US West (Oregon)',
value: 'us3',
},
{
label: 'Asia Pacific (Sydney)',
value: 'ap4',
},
{
label: 'EU (Ireland)',
value: 'eu',
},
{
label: 'South America (São Paulo)',
value: 'sa1',
},
],
ossRegions: [
{
label: 'China (Hangzhou)',
@@ -655,9 +820,55 @@ export default {
postmark: {
token: undefined,
},
broadcast: {
driver: undefined,
id: undefined,
key: undefined,
secret: undefined,
cluster: undefined,
port: undefined,
host: undefined,
}
}
},
methods: {
async broadcastSetupSubmit() {
// Validate fields
const isValid = await this.$refs.broadcastSetup.validate()
if (!isValid) return
// Start loading
this.isSendingBroadcastForm = true
axios
.post('/api/admin/settings/broadcast', {...this.broadcast})
.then(() => {
events.$emit('toaster', {
type: 'success',
message: this.$t('Your broadcast driver was updated.'),
})
})
.catch(() => {
events.$emit('toaster', {
type: 'danger',
message: this.$t('popup_error.title'),
})
})
.finally(() => {
this.isSendingBroadcastForm = false
this.broadcast = {
driver: undefined,
id: undefined,
key: undefined,
secret: undefined,
cluster: undefined,
host: undefined,
port: undefined,
}
})
},
async storageSetupSubmit() {
// Validate fields
const isValid = await this.$refs.storageSetup.validate()
@@ -696,7 +907,7 @@ export default {
}
})
},
async EmailSetupSubmit() {
async emailSetupSubmit() {
// Validate fields
const isValid = await this.$refs.EmailSetup.validate()

View File

@@ -363,6 +363,98 @@
</div>
</div>
<div class="card text-left shadow-card">
<FormLabel icon="wifi">
{{ $t('Broadcasting') }}
</FormLabel>
<ValidationProvider tag="div" mode="passive" name="Broadcast Driver" rules="required" v-slot="{ errors }">
<AppInputText title="Broadcast Driver" :error="errors[0]" :is-last="broadcast.driver === 'none' || broadcast.driver === undefined">
<SelectInput
v-model="broadcast.driver"
:options="broadcastDrivers"
placeholder="Select your broadcast driver"
:isError="errors[0]"
/>
</AppInputText>
</ValidationProvider>
<div v-if="broadcast.driver === 'native'">
<ValidationProvider tag="div" mode="passive" name="Host" rules="required" v-slot="{ errors }">
<AppInputText title="Hostname or IP" :error="errors[0]">
<input
class="focus-border-theme input-dark"
v-model="broadcast.host"
placeholder="Type your hostname or IP"
type="text"
:class="{ '!border-rose-600': errors[0] }"
/>
</AppInputText>
</ValidationProvider>
<ValidationProvider tag="div" mode="passive" name="Port" rules="required" v-slot="{ errors }">
<AppInputText title="Port" :error="errors[0]" :is-last="true">
<input
class="focus-border-theme input-dark"
v-model="broadcast.port"
placeholder="Type your port"
type="text"
:class="{ '!border-rose-600': errors[0] }"
/>
</AppInputText>
</ValidationProvider>
</div>
<div v-if="broadcast.driver === 'pusher'">
<ValidationProvider tag="div" mode="passive" name="App ID" rules="required" v-slot="{ errors }">
<AppInputText title="App ID" :error="errors[0]">
<input
class="focus-border-theme input-dark"
v-model="broadcast.id"
placeholder="Type your app id"
type="text"
:class="{ '!border-rose-600': errors[0] }"
/>
</AppInputText>
</ValidationProvider>
<ValidationProvider tag="div" mode="passive" name="Key" rules="required" v-slot="{ errors }">
<AppInputText title="Key" :error="errors[0]">
<input
class="focus-border-theme input-dark"
v-model="broadcast.key"
placeholder="Paste your key"
type="text"
:class="{ '!border-rose-600': errors[0] }"
/>
</AppInputText>
</ValidationProvider>
<ValidationProvider tag="div" mode="passive" name="Secret" rules="required" v-slot="{ errors }">
<AppInputText title="Secret" :error="errors[0]">
<input
class="focus-border-theme input-dark"
v-model="broadcast.secret"
placeholder="Paste your secret"
type="text"
:class="{ '!border-rose-600': errors[0] }"
/>
</AppInputText>
</ValidationProvider>
<ValidationProvider tag="div" mode="passive" name="Cluster" rules="required" v-slot="{ errors }">
<AppInputText title="Cluster" :error="errors[0]" :is-last="true">
<SelectInput
v-model="broadcast.cluster"
:options="pusherClusters"
placeholder="Select your cluster"
:isError="errors[0]"
/>
</AppInputText>
</ValidationProvider>
</div>
</div>
<div class="card text-left shadow-card">
<FormLabel>Environment Setup</FormLabel>
@@ -738,6 +830,67 @@ export default {
postmark: {
token: undefined,
},
broadcast: {
driver: undefined,
id: undefined,
key: undefined,
secret: undefined,
cluster: undefined,
port: undefined,
host: undefined,
},
broadcastDrivers: [
{
label: 'Pusher',
value: 'pusher',
},
{
label: 'VueFileManager Broadcast Server',
value: 'native',
},
{
label: 'None',
value: 'none',
},
],
pusherClusters: [
{
label: 'US East (N. Virginia)',
value: 'mt1',
},
{
label: 'Asia Pacific (Singapore)',
value: 'ap1',
},
{
label: 'Asia Pacific (Mumbai)',
value: 'ap2',
},
{
label: 'US East (Ohio)',
value: 'us2',
},
{
label: 'Asia Pacific (Tokyo)',
value: 'ap3',
},
{
label: 'US West (Oregon)',
value: 'us3',
},
{
label: 'Asia Pacific (Sydney)',
value: 'ap4',
},
{
label: 'EU (Ireland)',
value: 'eu',
},
{
label: 'South America (São Paulo)',
value: 'sa1',
},
],
}
},
methods: {
@@ -758,6 +911,7 @@ export default {
// Send request to get verify account
axios
.post('/api/setup/environment-setup', {
broadcast: this.broadcast,
environment: this.environment,
storage: this.storage,
mailDriver: this.mailDriver,

View File

@@ -74,12 +74,15 @@
// todo: refactoring
let config = {
ip: '{{ config('broadcasting.connections.pusher.options.host') }}',
host: '{{ url('/') }}',
api: '{{ url('/api') }}',
locale: '{{ app()->getLocale() }}',
broadcasting: '{{ config('broadcasting.default') }}',
broadcastingKey: '{{ config('broadcasting.connections.pusher.key') }}',
broadcastingHost: '{{ config('broadcasting.connections.pusher.options.host') }}',
broadcastingPort: '{{ config('broadcasting.connections.pusher.options.port') }}',
broadcastingCluster: '{{ config('broadcasting.connections.pusher.options.cluster') }}',
app_logo: '{{ $settings->app_logo ?? null }}',
app_logo_dark: '{{ $settings->app_logo_dark ?? null }}',

View File

@@ -9,6 +9,7 @@ use Domain\Settings\Controllers\GetServerStatusController;
use Domain\Settings\Controllers\GetSettingsValueController;
use Domain\Admin\Controllers\Dashboard\GetNewbiesController;
use Domain\Admin\Controllers\Users\ChangeUserRoleController;
use Domain\Settings\Controllers\StoreBroadcastServiceCredentialsController;
use Domain\Settings\Controllers\UpdateSettingValueController;
use Domain\Admin\Controllers\Users\ResetUserPasswordController;
use Domain\Settings\Controllers\StoreEmailCredentialsController;
@@ -55,6 +56,7 @@ Route::group(['prefix' => 'settings'], function () {
Route::post('/payment-service', StorePaymentServiceCredentialsController::class);
Route::post('/social-service', StoreSocialServiceCredentialsController::class);
Route::post('/broadcast', StoreBroadcastServiceCredentialsController::class);
});
// Language

View File

@@ -0,0 +1,58 @@
<?php
namespace Domain\Settings\Controllers;
use Artisan;
use Domain\Settings\Requests\StoreBroadcastServiceCredentialsRequest;
use Illuminate\Http\Response;
class StoreBroadcastServiceCredentialsController
{
/**
* Configure stripe additionally
*/
public function __invoke(StoreBroadcastServiceCredentialsRequest $request): Response
{
// Abort in demo mode
abort_if(is_demo(), 204, 'Done.');
// Get and store credentials
if (!app()->runningUnitTests()) {
$credentials = [
'pusher' => [
'BROADCAST_DRIVER' => 'pusher',
'PUSHER_APP_ID' => $request->input('id'),
'PUSHER_APP_KEY' => $request->input('key'),
'PUSHER_APP_SECRET' => $request->input('secret'),
'PUSHER_APP_CLUSTER' => $request->input('cluster'),
'PUSHER_APP_HOST' => '',
'PUSHER_APP_PORT' => '',
],
'native' => [
'BROADCAST_DRIVER' => 'pusher',
'PUSHER_APP_ID' => 'local',
'PUSHER_APP_KEY' => 'local',
'PUSHER_APP_SECRET' => 'local',
'PUSHER_APP_CLUSTER' => 'local',
'PUSHER_APP_HOST' => $request->input('host'),
'PUSHER_APP_PORT' => $request->input('port'),
],
'none' => [
'BROADCAST_DRIVER' => 'null',
],
];
// Store credentials into the .env file
setEnvironmentValue($credentials[$request->input('driver')]);
// Clear cache
if (!is_dev()) {
Artisan::call('cache:clear');
Artisan::call('config:clear');
Artisan::call('config:cache');
}
}
return response('Done', 204);
}
}

View File

@@ -0,0 +1,36 @@
<?php
namespace Domain\Settings\Requests;
use Illuminate\Foundation\Http\FormRequest;
class StoreBroadcastServiceCredentialsRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'driver' => 'required|string',
'id' => 'sometimes|nullable|string',
'key' => 'sometimes|nullable|string',
'secret' => 'sometimes|nullable|string',
'cluster' => 'sometimes|nullable|string',
'port' => 'sometimes|nullable|string',
'host' => 'sometimes|nullable|string',
];
}
}

View File

@@ -1,4 +1,5 @@
<?php
namespace Domain\SetupWizard\Controllers;
use Artisan;
@@ -13,89 +14,102 @@ class StoreEnvironmentSettingsController extends Controller
*/
public function __invoke(
StoreEnvironmentSetupRequest $request,
): Response {
if (! app()->runningUnitTests()) {
$drivers = [
'local' => [
'FILESYSTEM_DISK' => 'local',
): Response
{
if (!app()->runningUnitTests()) {
$setup = [
'broadcasting' => [
'pusher' => [
'BROADCAST_DRIVER' => 'pusher',
'PUSHER_APP_ID' => $request->input('broadcast.id'),
'PUSHER_APP_KEY' => $request->input('broadcast.key'),
'PUSHER_APP_SECRET' => $request->input('broadcast.secret'),
'PUSHER_APP_CLUSTER' => $request->input('broadcast.cluster'),
],
'native' => [
'BROADCAST_DRIVER' => 'pusher',
'PUSHER_APP_ID' => 'local',
'PUSHER_APP_KEY' => 'local',
'PUSHER_APP_SECRET' => 'local',
'PUSHER_APP_CLUSTER' => 'local',
'PUSHER_APP_HOST' => $request->input('broadcast.host'),
'PUSHER_APP_PORT' => $request->input('broadcast.port'),
],
'none' => [
'BROADCAST_DRIVER' => 'null',
],
],
's3' => [
'FILESYSTEM_DISK' => 's3',
'S3_ACCESS_KEY_ID' => $request->input('storage.key') ?? null,
'S3_SECRET_ACCESS_KEY' => $request->input('storage.secret') ?? null,
'S3_DEFAULT_REGION' => $request->input('storage.region') ?? null,
'S3_BUCKET' => $request->input('storage.bucket') ?? null,
'S3_URL' => $request->input('storage.endpoint') ?? null,
'drivers' => [
'local' => [
'FILESYSTEM_DISK' => 'local',
],
's3' => [
'FILESYSTEM_DISK' => 's3',
'S3_ACCESS_KEY_ID' => $request->input('storage.key') ?? null,
'S3_SECRET_ACCESS_KEY' => $request->input('storage.secret') ?? null,
'S3_DEFAULT_REGION' => $request->input('storage.region') ?? null,
'S3_BUCKET' => $request->input('storage.bucket') ?? null,
'S3_URL' => $request->input('storage.endpoint') ?? null,
],
],
'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'),
],
],
'environment' => [
'production' => [
'APP_ENV' => 'production',
'APP_DEBUG' => 'false',
],
'local' => [
'APP_ENV' => 'local',
'APP_DEBUG' => 'true',
'QUEUE_CONNECTION' => 'sync',
],
],
'others' => [
'APP_URL' => url('/'),
'SANCTUM_STATEFUL_DOMAINS' => request()->getHost() . ',' . request()->getHost() . ':' . request()->getPort(),
],
];
// Get storage driver from request
$driver = 'local' === $request->input('storage.driver') ? 'local' : 's3';
// Storage credentials for storage
setEnvironmentValue(
$drivers[$driver]
);
$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')]
);
$environmentSetup = [
'production' => [
'APP_ENV' => 'production',
'APP_DEBUG' => 'false',
],
'local' => [
'APP_ENV' => 'local',
'APP_DEBUG' => 'true',
'QUEUE_CONNECTION' => 'sync',
],
];
setEnvironmentValue(
$environmentSetup[$request->input('environment')]
);
$sanctumStatefulDomains = request()->getHost() . ',' . request()->getHost() . ':' . request()->getPort();
// Set other environment variables
setEnvironmentValue([
'APP_URL' => url('/'),
'SANCTUM_STATEFUL_DOMAINS' => $sanctumStatefulDomains,
]);
setEnvironmentValue(array_merge(
$setup['broadcasting'][$request->input('broadcast.driver')],
$setup['environment'][$request->input('environment')],
$setup['mail'][$request->input('mailDriver')],
$setup['drivers'][$driver],
$setup['others'],
));
Artisan::call('config:cache');
}

View File

@@ -1,4 +1,5 @@
<?php
namespace Domain\SetupWizard\Requests;
use Illuminate\Foundation\Http\FormRequest;
@@ -23,6 +24,7 @@ class StoreEnvironmentSetupRequest extends FormRequest
public function rules()
{
return [
'broadcast' => 'required|array',
'storage' => 'required|array',
'environment' => 'required|string',
'storage.driver' => 'required|string',

View File

@@ -220,4 +220,25 @@ class SettingsTest extends TestCase
],
])->assertStatus(204);
}
/**
* @test
*/
public function it_set_broadcast()
{
$admin = User::factory()
->create(['role' => 'admin']);
$this
->actingAs($admin)
->postJson('/api/admin/settings/broadcast', [
'driver' => 'pusher',
'id' => '123',
'key' => '123456',
'secret' => 'mOoiofnssddf',
'cluster' => 'eu',
'port' => null,
'host' => null,
])->assertStatus(204);
}
}