Compare commits
136 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fbcaee3bdc | ||
|
|
3082c10cdb | ||
|
|
a4d90f0017 | ||
|
|
8adfc9837e | ||
|
|
aa20c8a42b | ||
|
|
0f100d6159 | ||
|
|
7c896243a5 | ||
|
|
954fef7c3e | ||
|
|
105126e498 | ||
|
|
7aa5a8949d | ||
|
|
27079928a7 | ||
|
|
99968e57ec | ||
|
|
f75bc1a551 | ||
|
|
ef347f9381 | ||
|
|
f1aace3d8f | ||
|
|
b2bec62766 | ||
|
|
3a8682bbed | ||
|
|
5cfc1f97fe | ||
|
|
cfc8220f8e | ||
|
|
ac5ffefaed | ||
|
|
cbd2b8e0e9 | ||
|
|
f0f427a7bb | ||
|
|
7b6f651015 | ||
|
|
c793daa79a | ||
|
|
71b436aebe | ||
|
|
06e108da5b | ||
|
|
5677c58dd2 | ||
|
|
58ca801e30 | ||
|
|
e750d7caba | ||
|
|
3c0964ef0e | ||
|
|
33613cdf1c | ||
|
|
abfe174825 | ||
|
|
c750f469bb | ||
|
|
c7ac56d5cc | ||
|
|
6601f44013 | ||
|
|
b7baf862b6 | ||
|
|
ca79f4cf21 | ||
|
|
58ffbe8c74 | ||
|
|
dfa7b995fc | ||
|
|
59c65fe6ee | ||
|
|
087c042c14 | ||
|
|
d1ee488ffd | ||
|
|
34100bc580 | ||
|
|
22d91517fb | ||
|
|
1c088bd4e0 | ||
|
|
fd5bbb7f5d | ||
|
|
426d39bec0 | ||
|
|
8244c2dfb2 | ||
|
|
e7f9d32f68 | ||
|
|
71158a0030 | ||
|
|
573ce14b7a | ||
|
|
00ef1f470f | ||
|
|
a9357034c8 | ||
|
|
a45f5157d4 | ||
|
|
0d1009b8db | ||
|
|
4f0416cd45 | ||
|
|
76655d76d5 | ||
|
|
3b38cbe9ac | ||
|
|
acf37b8850 | ||
|
|
f47a0699d3 | ||
|
|
8ae429b06b | ||
|
|
626dbbcb49 | ||
|
|
b623dd80fd | ||
|
|
3978a7c9f7 | ||
|
|
7d2acb7438 | ||
|
|
096032301c | ||
|
|
c3e99bf2ff | ||
|
|
9795642bc7 | ||
|
|
4281a432fb | ||
|
|
18df5589b1 | ||
|
|
79536eac2e | ||
|
|
6df82fca04 | ||
|
|
cc14123d27 | ||
|
|
bd5e7b87ff | ||
|
|
42568916d6 | ||
|
|
180803cd8a | ||
|
|
08fcb0ce01 | ||
|
|
120b4c9df7 | ||
|
|
0eb66c10f6 | ||
|
|
1a6b14a250 | ||
|
|
072c8569eb | ||
|
|
5b9378255b | ||
|
|
ac3cf16377 | ||
|
|
31154d20f6 | ||
|
|
f8031ac71a | ||
|
|
898ec6a454 | ||
|
|
9dbd54fdf6 | ||
|
|
934017384d | ||
|
|
aee3dc0d93 | ||
|
|
8046687ae7 | ||
|
|
a89ee796c1 | ||
|
|
af1d3c3edc | ||
|
|
e1a54c2781 | ||
|
|
2d9f7d49b5 | ||
|
|
d10b046033 | ||
|
|
1725c0ff65 | ||
|
|
b852756c82 | ||
|
|
f164d878d7 | ||
|
|
ecc10fffcb | ||
|
|
5c75b015ba | ||
|
|
65f7dc697e | ||
|
|
d981f0f899 | ||
|
|
ab50beefab | ||
|
|
58d1215fd6 | ||
|
|
1dc137c314 | ||
|
|
ca51e9bf5f | ||
|
|
c588583dfc | ||
|
|
57c7c53eae | ||
|
|
76a62d9992 | ||
|
|
575aa1c6b1 | ||
|
|
4867a61fd0 | ||
|
|
a63e8f350b | ||
|
|
6c1b4f28af | ||
|
|
09adccf752 | ||
|
|
79bb522dee | ||
|
|
2adc4bc7ca | ||
|
|
0a81d58051 | ||
|
|
cb84438778 | ||
|
|
b0a76d311c | ||
|
|
5604503d26 | ||
|
|
bf55092b3a | ||
|
|
8286e7f9af | ||
|
|
1255221550 | ||
|
|
f4062cd6e7 | ||
|
|
93377ae753 | ||
|
|
a43cd19efd | ||
|
|
e5eec000d3 | ||
|
|
e5c8a62b32 | ||
|
|
9ae1c145b6 | ||
|
|
eb8b75e4f9 | ||
|
|
7378b82adf | ||
|
|
6f3b588f3d | ||
|
|
a2154cf37c | ||
|
|
9dab5f8093 | ||
|
|
9c9469d2f6 | ||
|
|
94acc313b1 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -12,3 +12,4 @@ npm-debug.log
|
||||
yarn-error.log
|
||||
.idea
|
||||
.php_cs.cache
|
||||
/public/js/resources*.js
|
||||
|
||||
@@ -8,11 +8,11 @@ $finder = Symfony\Component\Finder\Finder::create()
|
||||
->name('*.php')
|
||||
->notName('*.blade.php');
|
||||
|
||||
return PhpCsFixer\Config::create()
|
||||
return (new PhpCsFixer\Config)
|
||||
->setRules([
|
||||
'@PSR2' => true,
|
||||
'array_syntax' => ['syntax' => 'short'],
|
||||
'ordered_imports' => ['sortAlgorithm' => 'length'],
|
||||
'ordered_imports' => ['sort_algorithm' => 'length'],
|
||||
'no_unused_imports' => true,
|
||||
])
|
||||
->setFinder($finder);
|
||||
@@ -3,7 +3,7 @@
|
||||
With Ploi Core, you'll power-launch your webhosting company.
|
||||
Using the ploi.io system as backbone you will be able to serve your customers your custom panel & feeling.
|
||||
|
||||
<p align="center"><img src="https://ploi-core.io/images/featured.png" width="100%"></p>
|
||||
<p align="center"><img src="https://ploi-core.io/images/og.jpg" width="100%"></p>
|
||||
|
||||
## Documentation
|
||||
|
||||
|
||||
31
app/Console/Commands/Core/Css.php
Normal file
31
app/Console/Commands/Core/Css.php
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands\Core;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Filesystem\Filesystem;
|
||||
|
||||
class Css extends Command
|
||||
{
|
||||
protected $signature = 'core:css';
|
||||
|
||||
protected $description = 'Generates an theme.css file for you to customize';
|
||||
|
||||
public function handle()
|
||||
{
|
||||
if (file_exists(storage_path('app/public/theme.css')) && !$this->confirm('You seem to already have a theme.css published, are you sure you want to overwrite?')) {
|
||||
$this->warn('Aborted publishing of theme.css.');
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
$this->info('Publishing theme.css file..');
|
||||
|
||||
(new Filesystem)->copy(
|
||||
__DIR__ . '/stubs/theme.css',
|
||||
storage_path('app/public/theme.css')
|
||||
);
|
||||
|
||||
$this->info('Done! You can edit the theme.css file inside storage/public/theme.css');
|
||||
}
|
||||
}
|
||||
31
app/Console/Commands/Core/CssBackup.php
Normal file
31
app/Console/Commands/Core/CssBackup.php
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace App\Console\Commands\Core;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Filesystem\Filesystem;
|
||||
|
||||
class CssBackup extends Command
|
||||
{
|
||||
protected $signature = 'core:css-backup';
|
||||
|
||||
protected $description = 'Creates a backup from your own created theme.css';
|
||||
|
||||
public function handle()
|
||||
{
|
||||
if (!file_exists(storage_path('app/public/theme.css'))) {
|
||||
$this->warn('There is no custom theme.css, aborting backup.');
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
$this->info('Backing up theme.css file..');
|
||||
|
||||
(new Filesystem)->copy(
|
||||
storage_path('app/public/theme.css'),
|
||||
storage_path('app/public/theme-backup.css')
|
||||
);
|
||||
|
||||
$this->info('Done! You can find the CSS backup file here storage/public/theme-backup.css');
|
||||
}
|
||||
}
|
||||
@@ -7,16 +7,18 @@ use App\Models\User;
|
||||
use RuntimeException;
|
||||
use App\Models\Package;
|
||||
use App\Services\Ploi\Ploi;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Console\Command;
|
||||
use App\Services\VersionChecker;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use Illuminate\Support\Facades\Artisan;
|
||||
|
||||
class Install extends Command
|
||||
{
|
||||
protected $company;
|
||||
protected $signature = 'core:install';
|
||||
protected $signature = 'core:install {--force}';
|
||||
protected $description = 'Installation command for Ploi Core';
|
||||
protected $versionChecker;
|
||||
protected $installationFile = 'app/installation';
|
||||
@@ -34,8 +36,14 @@ class Install extends Command
|
||||
$this->askAboutDefaultPackages();
|
||||
$this->checkApplicationUrl();
|
||||
$this->createInstallationFile();
|
||||
$this->linkStorage();
|
||||
|
||||
$this->info('Succes! Installation has finished.');
|
||||
$this->info('Success! Installation has finished.');
|
||||
$this->line(' ');
|
||||
$this->writeSeparationLine();
|
||||
$this->info('Make sure to also setup emailing, the cronjob and the queue worker.');
|
||||
$this->writeSeparationLine();
|
||||
$this->line(' ');
|
||||
$this->info('Visit your platform at ' . env('APP_URL'));
|
||||
}
|
||||
|
||||
@@ -98,7 +106,7 @@ class Install extends Command
|
||||
|
||||
Package::create([
|
||||
'name' => 'Professional',
|
||||
'maximum_sites' => 5,
|
||||
'maximum_sites' => 30,
|
||||
'site_permissions' => [
|
||||
'create' => true,
|
||||
'update' => true,
|
||||
@@ -138,7 +146,9 @@ class Install extends Command
|
||||
->get((new Ploi)->url . 'ping');
|
||||
|
||||
if (!$response->ok() || !$response->json()) {
|
||||
return false;
|
||||
return [
|
||||
'error' => Arr::get($response->json(), 'message', 'An unknown error has occurred.')
|
||||
];
|
||||
}
|
||||
|
||||
return $response->json();
|
||||
@@ -153,7 +163,7 @@ class Install extends Command
|
||||
|
||||
protected function intro()
|
||||
{
|
||||
$this->info('*---------------------------------------------------------------------------*');
|
||||
$this->writeSeparationLine();
|
||||
$this->line('Ploi Core Installation');
|
||||
$this->line('Ploi Core version: ' . $this->versionChecker->currentVersion);
|
||||
$this->line('Ploi Core remote: ' . $this->versionChecker->remoteVersion);
|
||||
@@ -163,13 +173,13 @@ class Install extends Command
|
||||
$this->line('Website: https://ploi-core.io');
|
||||
$this->line('E-mail: core@ploi.io');
|
||||
$this->line('Terms of service: https://ploi-core.io/terms');
|
||||
$this->info('*---------------------------------------------------------------------------*');
|
||||
$this->writeSeparationLine();
|
||||
$this->line('');
|
||||
}
|
||||
|
||||
protected function isInstalled()
|
||||
{
|
||||
if (file_exists(storage_path($this->installationFile))) {
|
||||
if (file_exists(storage_path($this->installationFile)) && !$this->option('force')) {
|
||||
$this->line('');
|
||||
$this->comment('Ploi Core has already been installed before.');
|
||||
$this->comment('If you still want to start installation, remove this file to continue: ./storage/' . $this->installationFile);
|
||||
@@ -203,6 +213,11 @@ class Install extends Command
|
||||
file_put_contents(storage_path($this->installationFile), json_encode($this->getInstallationPayload(), JSON_PRETTY_PRINT));
|
||||
}
|
||||
|
||||
protected function linkStorage()
|
||||
{
|
||||
Artisan::call('storage:link');
|
||||
}
|
||||
|
||||
protected function createDatabaseCredentials(): bool
|
||||
{
|
||||
$storeCredentials = $this->confirm(
|
||||
@@ -269,6 +284,18 @@ class Install extends Command
|
||||
exit();
|
||||
}
|
||||
|
||||
if (isset($this->company['error'])) {
|
||||
$this->error($this->company['error']);
|
||||
|
||||
exit();
|
||||
}
|
||||
|
||||
if ($this->company['user']['subscription'] !== 'unlimited') {
|
||||
$this->error('Your subscription does not cover the usage of Ploi Core. Please upgrade your subscription to Unlimited.');
|
||||
|
||||
exit();
|
||||
}
|
||||
|
||||
$this->writeToEnvironmentFile('PLOI_TOKEN', $ploiApiToken);
|
||||
$this->writeToEnvironmentFile('PLOI_CORE_TOKEN', $ploiCoreKey);
|
||||
|
||||
@@ -372,4 +399,9 @@ class Install extends Command
|
||||
{
|
||||
$this->laravel['config'][$key] = $value;
|
||||
}
|
||||
|
||||
protected function writeSeparationLine()
|
||||
{
|
||||
$this->info('*---------------------------------------------------------------------------*');
|
||||
}
|
||||
}
|
||||
|
||||
78
app/Console/Commands/Core/stubs/theme.css
vendored
Normal file
78
app/Console/Commands/Core/stubs/theme.css
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
:root {
|
||||
--font-body: 'Inter', sans-serif;
|
||||
|
||||
--color-white: #fff;
|
||||
--color-gray-1: #f7f7f7;
|
||||
--color-gray-2: #e6e6e6;
|
||||
--color-gray-3: #cacaca;
|
||||
--color-gray-4: #888;
|
||||
--color-gray-5: #666;
|
||||
--color-gray-6: #2f2f2f;
|
||||
--color-gray-7: #1b1a1a;
|
||||
--color-gray-8: #101010;
|
||||
|
||||
--color-primary: #1b8ae8;
|
||||
--color-success: #17b35d;
|
||||
--color-warning: #f5a623;
|
||||
--color-danger: #c90c4c;
|
||||
|
||||
--color-text-high-emphasis: var(--color-gray-8);
|
||||
--color-text-medium-emphasis: var(--color-gray-5);
|
||||
--color-text-low-emphasis: var(--color-gray-3);
|
||||
|
||||
--color-text-on-primary: var(--color-white);
|
||||
--color-text-on-success: var(--color-gray-8);
|
||||
--color-text-on-warning: var(--color-white);
|
||||
--color-text-on-danger: var(--color-white);
|
||||
|
||||
--color-border-high-emphasis: var(--color-gray-4);
|
||||
--color-border-medium-emphasis: var(--color-gray-3);
|
||||
--color-border-low-emphasis: var(--color-gray-2);
|
||||
|
||||
--color-backdrop: rgba(0, 0, 0, 0.5);
|
||||
--color-overlay: rgba(255, 255, 255, 0.8);
|
||||
--color-surface-1: var(--color-white);
|
||||
--color-surface-2: var(--color-gray-1);
|
||||
--color-surface-3: var(--color-white);
|
||||
|
||||
--border-radius: 0.5rem;
|
||||
--border-radius-avatar: 4rem;
|
||||
--border-radius-circle: 100%;
|
||||
|
||||
--top-bar-container: 64rem;
|
||||
--top-bar-logo-height: 3.5rem;
|
||||
--top-bar-background-color: var(--color-surface-1);
|
||||
--top-bar-text-color: var(--color-text-medium-emphasis);
|
||||
|
||||
--tab-bar-background-color: var(--color-surface-2);
|
||||
--tab-bar-item-active-background-color: var(--color-surface-1);
|
||||
--tab-bar-item-text-color: var(--color-text-medium-emphasis);
|
||||
--tab-bar-item-active-text-color: var(--color-text-high-emphasis);
|
||||
|
||||
--breadcrumbs-text-color: var(--color-text-medium-emphasis);
|
||||
}
|
||||
|
||||
.theme--dark {
|
||||
--color-primary: #63a6f5;
|
||||
--color-success: #50e3c2;
|
||||
--color-warning: #f5a623;
|
||||
--color-danger: #d4667c;
|
||||
|
||||
--color-text-high-emphasis: var(--color-white);
|
||||
--color-text-medium-emphasis: var(--color-gray-3);
|
||||
--color-text-low-emphasis: var(--color-gray-5);
|
||||
|
||||
--color-text-on-primary: var(--color-gray-7);
|
||||
--color-text-on-success: var(--color-gray-7);
|
||||
--color-text-on-warning: var(--color-gray-7);
|
||||
--color-text-on-danger: var(--color-gray-7);
|
||||
|
||||
--color-border-high-emphasis: var(--color-gray-4);
|
||||
--color-border-medium-emphasis: var(--color-gray-5);
|
||||
--color-border-low-emphasis: var(--color-gray-6);
|
||||
|
||||
--color-surface-1: var(--color-gray-7);
|
||||
--color-surface-2: var(--color-gray-6);
|
||||
--color-surface-3: var(--color-gray-6);
|
||||
--color-overlay: rgba(0, 0, 0, 0.8);
|
||||
}
|
||||
@@ -3,7 +3,9 @@
|
||||
namespace App\Console;
|
||||
|
||||
use App\Jobs\Core\Ping;
|
||||
use App\Console\Commands\Core\Css;
|
||||
use App\Console\Commands\Core\Install;
|
||||
use App\Console\Commands\Core\CssBackup;
|
||||
use App\Console\Commands\Core\Synchronize;
|
||||
use Illuminate\Console\Scheduling\Schedule;
|
||||
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
|
||||
@@ -11,6 +13,8 @@ use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
|
||||
class Kernel extends ConsoleKernel
|
||||
{
|
||||
protected $commands = [
|
||||
Css::class,
|
||||
CssBackup::class,
|
||||
Install::class,
|
||||
Synchronize::class,
|
||||
];
|
||||
|
||||
281
app/Helpers/Country.php
Normal file
281
app/Helpers/Country.php
Normal file
@@ -0,0 +1,281 @@
|
||||
<?php
|
||||
|
||||
if (!function_exists('countries')) {
|
||||
function countries($key = null)
|
||||
{
|
||||
$arr = [
|
||||
'af' => 'Afghanistan',
|
||||
'al' => 'Albania',
|
||||
'dz' => 'Algeria',
|
||||
'as' => 'American Samoa',
|
||||
'ad' => 'Andorra',
|
||||
'ao' => 'Angola',
|
||||
'ai' => 'Anguilla',
|
||||
'aq' => 'Antarctica',
|
||||
'ag' => 'Antigua and Barbuda',
|
||||
'ar' => 'Argentina',
|
||||
'am' => 'Armenia',
|
||||
'aw' => 'Aruba',
|
||||
'au' => 'Australia',
|
||||
'at' => 'Austria',
|
||||
'az' => 'Azerbaijan',
|
||||
'bs' => 'Bahamas',
|
||||
'bh' => 'Bahrain',
|
||||
'bd' => 'Bangladesh',
|
||||
'bb' => 'Barbados',
|
||||
'by' => 'Belarus',
|
||||
'be' => 'Belgium',
|
||||
'bz' => 'Belize',
|
||||
'bj' => 'Benin',
|
||||
'bm' => 'Bermuda',
|
||||
'bt' => 'Bhutan',
|
||||
'bo' => 'Bolivia',
|
||||
'ba' => 'Bosnia and Herzegovina',
|
||||
'bw' => 'Botswana',
|
||||
'bv' => 'Bouvet Island',
|
||||
'br' => 'Brazil',
|
||||
'bq' => 'British Antarctic Territory',
|
||||
'io' => 'British Indian Ocean Territory',
|
||||
'vg' => 'British Virgin Islands',
|
||||
'bn' => 'Brunei',
|
||||
'bg' => 'Bulgaria',
|
||||
'bf' => 'Burkina Faso',
|
||||
'bi' => 'Burundi',
|
||||
'kh' => 'Cambodia',
|
||||
'cm' => 'Cameroon',
|
||||
'ca' => 'Canada',
|
||||
'ct' => 'Canton and Enderbury Islands',
|
||||
'cv' => 'Cape Verde',
|
||||
'ky' => 'Cayman Islands',
|
||||
'cf' => 'Central African Republic',
|
||||
'td' => 'Chad',
|
||||
'cl' => 'Chile',
|
||||
'cn' => 'China',
|
||||
'cx' => 'Christmas Island',
|
||||
'cc' => 'Cocos [Keeling] Islands',
|
||||
'co' => 'Colombia',
|
||||
'km' => 'Comoros',
|
||||
'cg' => 'Congo - Brazzaville',
|
||||
'cd' => 'Congo - Kinshasa',
|
||||
'ck' => 'Cook Islands',
|
||||
'cr' => 'Costa Rica',
|
||||
'hr' => 'Croatia',
|
||||
'cu' => 'Cuba',
|
||||
'cy' => 'Cyprus',
|
||||
'cz' => 'Czech Republic',
|
||||
'ci' => 'Côte d’Ivoire',
|
||||
'dk' => 'Denmark',
|
||||
'dj' => 'Djibouti',
|
||||
'dm' => 'Dominica',
|
||||
'do' => 'Dominican Republic',
|
||||
'nq' => 'Dronning Maud Land',
|
||||
'dd' => 'East Germany',
|
||||
'ec' => 'Ecuador',
|
||||
'eg' => 'Egypt',
|
||||
'sv' => 'El Salvador',
|
||||
'gq' => 'Equatorial Guinea',
|
||||
'er' => 'Eritrea',
|
||||
'ee' => 'Estonia',
|
||||
'et' => 'Ethiopia',
|
||||
'fk' => 'Falkland Islands',
|
||||
'fo' => 'Faroe Islands',
|
||||
'fj' => 'Fiji',
|
||||
'fi' => 'Finland',
|
||||
'fr' => 'France',
|
||||
'gf' => 'French Guiana',
|
||||
'pf' => 'French Polynesia',
|
||||
'tf' => 'French Southern Territories',
|
||||
'fq' => 'French Southern and Antarctic Territories',
|
||||
'ga' => 'Gabon',
|
||||
'gm' => 'Gambia',
|
||||
'ge' => 'Georgia',
|
||||
'de' => 'Germany',
|
||||
'gh' => 'Ghana',
|
||||
'gi' => 'Gibraltar',
|
||||
'gr' => 'Greece',
|
||||
'gl' => 'Greenland',
|
||||
'gd' => 'Grenada',
|
||||
'gp' => 'Guadeloupe',
|
||||
'gu' => 'Guam',
|
||||
'gt' => 'Guatemala',
|
||||
'gg' => 'Guernsey',
|
||||
'gn' => 'Guinea',
|
||||
'gw' => 'Guinea-Bissau',
|
||||
'gy' => 'Guyana',
|
||||
'ht' => 'Haiti',
|
||||
'hm' => 'Heard Island and McDonald Islands',
|
||||
'hn' => 'Honduras',
|
||||
'hk' => 'Hong Kong SAR China',
|
||||
'hu' => 'Hungary',
|
||||
'is' => 'Iceland',
|
||||
'in' => 'India',
|
||||
'id' => 'Indonesia',
|
||||
'ir' => 'Iran',
|
||||
'iq' => 'Iraq',
|
||||
'ie' => 'Ireland',
|
||||
'im' => 'Isle of Man',
|
||||
'il' => 'Israel',
|
||||
'it' => 'Italy',
|
||||
'jm' => 'Jamaica',
|
||||
'jp' => 'Japan',
|
||||
'je' => 'Jersey',
|
||||
'jt' => 'Johnston Island',
|
||||
'jo' => 'Jordan',
|
||||
'kz' => 'Kazakhstan',
|
||||
'ke' => 'Kenya',
|
||||
'ki' => 'Kiribati',
|
||||
'kw' => 'Kuwait',
|
||||
'kg' => 'Kyrgyzstan',
|
||||
'la' => 'Laos',
|
||||
'lv' => 'Latvia',
|
||||
'lb' => 'Lebanon',
|
||||
'ls' => 'Lesotho',
|
||||
'lr' => 'Liberia',
|
||||
'ly' => 'Libya',
|
||||
'li' => 'Liechtenstein',
|
||||
'lt' => 'Lithuania',
|
||||
'lu' => 'Luxembourg',
|
||||
'mo' => 'Macau SAR China',
|
||||
'mk' => 'Macedonia',
|
||||
'mg' => 'Madagascar',
|
||||
'mw' => 'Malawi',
|
||||
'my' => 'Malaysia',
|
||||
'mv' => 'Maldives',
|
||||
'ml' => 'Mali',
|
||||
'mt' => 'Malta',
|
||||
'mh' => 'Marshall Islands',
|
||||
'mq' => 'Martinique',
|
||||
'mr' => 'Mauritania',
|
||||
'mu' => 'Mauritius',
|
||||
'yt' => 'Mayotte',
|
||||
'fx' => 'Metropolitan France',
|
||||
'mx' => 'Mexico',
|
||||
'fm' => 'Micronesia',
|
||||
'mi' => 'Midway Islands',
|
||||
'md' => 'Moldova',
|
||||
'mc' => 'Monaco',
|
||||
'mn' => 'Mongolia',
|
||||
'me' => 'Montenegro',
|
||||
'ms' => 'Montserrat',
|
||||
'ma' => 'Morocco',
|
||||
'mz' => 'Mozambique',
|
||||
'mm' => 'Myanmar [Burma]',
|
||||
'na' => 'Namibia',
|
||||
'nr' => 'Nauru',
|
||||
'np' => 'Nepal',
|
||||
'nl' => 'Netherlands',
|
||||
'an' => 'Netherlands Antilles',
|
||||
'nt' => 'Neutral Zone',
|
||||
'nc' => 'New Caledonia',
|
||||
'nz' => 'New Zealand',
|
||||
'ni' => 'Nicaragua',
|
||||
'ne' => 'Niger',
|
||||
'ng' => 'Nigeria',
|
||||
'nu' => 'Niue',
|
||||
'nf' => 'Norfolk Island',
|
||||
'kp' => 'North Korea',
|
||||
'vd' => 'North Vietnam',
|
||||
'mp' => 'Northern Mariana Islands',
|
||||
'no' => 'Norway',
|
||||
'om' => 'Oman',
|
||||
'pc' => 'Pacific Islands Trust Territory',
|
||||
'pk' => 'Pakistan',
|
||||
'pw' => 'Palau',
|
||||
'ps' => 'Palestinian Territories',
|
||||
'pa' => 'Panama',
|
||||
'pz' => 'Panama Canal Zone',
|
||||
'pg' => 'Papua New Guinea',
|
||||
'py' => 'Paraguay',
|
||||
'yd' => 'People\'s Democratic Republic of Yemen',
|
||||
'pe' => 'Peru',
|
||||
'ph' => 'Philippines',
|
||||
'pn' => 'Pitcairn Islands',
|
||||
'pl' => 'Poland',
|
||||
'pt' => 'Portugal',
|
||||
'pr' => 'Puerto Rico',
|
||||
'qa' => 'Qatar',
|
||||
'ro' => 'Romania',
|
||||
'ru' => 'Russia',
|
||||
'rw' => 'Rwanda',
|
||||
're' => 'Réunion',
|
||||
'bl' => 'Saint Barthélemy',
|
||||
'sh' => 'Saint Helena',
|
||||
'kn' => 'Saint Kitts and Nevis',
|
||||
'lc' => 'Saint Lucia',
|
||||
'mf' => 'Saint Martin',
|
||||
'pm' => 'Saint Pierre and Miquelon',
|
||||
'vc' => 'Saint Vincent and the Grenadines',
|
||||
'ws' => 'Samoa',
|
||||
'sm' => 'San Marino',
|
||||
'sa' => 'Saudi Arabia',
|
||||
'sn' => 'Senegal',
|
||||
'rs' => 'Serbia',
|
||||
'cs' => 'Serbia and Montenegro',
|
||||
'sc' => 'Seychelles',
|
||||
'sl' => 'Sierra Leone',
|
||||
'sg' => 'Singapore',
|
||||
'sk' => 'Slovakia',
|
||||
'si' => 'Slovenia',
|
||||
'sb' => 'Solomon Islands',
|
||||
'so' => 'Somalia',
|
||||
'za' => 'South Africa',
|
||||
'gs' => 'South Georgia and the South Sandwich Islands',
|
||||
'kr' => 'South Korea',
|
||||
'es' => 'Spain',
|
||||
'lk' => 'Sri Lanka',
|
||||
'sd' => 'Sudan',
|
||||
'sr' => 'Suriname',
|
||||
'sj' => 'Svalbard and Jan Mayen',
|
||||
'sz' => 'Swaziland',
|
||||
'se' => 'Sweden',
|
||||
'ch' => 'Switzerland',
|
||||
'sy' => 'Syria',
|
||||
'st' => 'São Tomé and Príncipe',
|
||||
'tw' => 'Taiwan',
|
||||
'tj' => 'Tajikistan',
|
||||
'tz' => 'Tanzania',
|
||||
'th' => 'Thailand',
|
||||
'tl' => 'Timor-Leste',
|
||||
'tg' => 'Togo',
|
||||
'tk' => 'Tokelau',
|
||||
'to' => 'Tonga',
|
||||
'tt' => 'Trinidad and Tobago',
|
||||
'tn' => 'Tunisia',
|
||||
'tr' => 'Turkey',
|
||||
'tm' => 'Turkmenistan',
|
||||
'tc' => 'Turks and Caicos Islands',
|
||||
'tv' => 'Tuvalu',
|
||||
'um' => 'U.S. Minor Outlying Islands',
|
||||
'pu' => 'U.S. Miscellaneous Pacific Islands',
|
||||
'vi' => 'U.S. Virgin Islands',
|
||||
'ug' => 'Uganda',
|
||||
'ua' => 'Ukraine',
|
||||
'su' => 'Union of Soviet Socialist Republics',
|
||||
'ae' => 'United Arab Emirates',
|
||||
'en' => 'United Kingdom (EN)',
|
||||
'uk' => 'United Kingdom (UK)',
|
||||
'gb' => 'United Kingdom (GB)',
|
||||
'us' => 'United States',
|
||||
'zz' => 'Unknown or Invalid Region',
|
||||
'uy' => 'Uruguay',
|
||||
'uz' => 'Uzbekistan',
|
||||
'vu' => 'Vanuatu',
|
||||
'va' => 'Vatican City',
|
||||
've' => 'Venezuela',
|
||||
'vn' => 'Vietnam',
|
||||
'wk' => 'Wake Island',
|
||||
'wf' => 'Wallis and Futuna',
|
||||
'eh' => 'Western Sahara',
|
||||
'ye' => 'Yemen',
|
||||
'zm' => 'Zambia',
|
||||
'zw' => 'Zimbabwe',
|
||||
'ax' => 'Åland Islands',
|
||||
];
|
||||
|
||||
if ($key && array_key_exists($key, $arr)) {
|
||||
return $arr[strtolower($key)];
|
||||
}
|
||||
|
||||
return $arr;
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
<?php
|
||||
|
||||
if (!function_exists('languages')) {
|
||||
function languages()
|
||||
function languages(): array
|
||||
{
|
||||
$languages = [
|
||||
'en'
|
||||
|
||||
80
app/Http/Controllers/Admin/AlertController.php
Normal file
80
app/Http/Controllers/Admin/AlertController.php
Normal file
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Models\Alert;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Admin\AlertRequest;
|
||||
|
||||
class AlertController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
return inertia('Admin/Alerts/Index', [
|
||||
'alerts' => Alert::query()->latest()->paginate()
|
||||
]);
|
||||
}
|
||||
|
||||
public function create()
|
||||
{
|
||||
return inertia('Admin/Alerts/Create');
|
||||
}
|
||||
|
||||
public function store(AlertRequest $request)
|
||||
{
|
||||
Alert::create($request->all());
|
||||
|
||||
return redirect()->route('admin.alerts.index');
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function show($id)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function edit($id)
|
||||
{
|
||||
return inertia('Admin/Alerts/Edit', [
|
||||
'alert' => Alert::findOrFail($id)
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function update(AlertRequest $request, $id)
|
||||
{
|
||||
Alert::findOrFail($id)->update($request->all());
|
||||
|
||||
return redirect()->route('admin.alerts.index');
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function destroy($id)
|
||||
{
|
||||
Alert::findOrFail($id)->delete();
|
||||
|
||||
return redirect()->route('admin.alerts.index');
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,8 @@ class ProviderController extends Controller
|
||||
|
||||
return inertia('Admin/Services/Provider/Edit', [
|
||||
'provider' => $provider,
|
||||
'availablePlans' => $provider->plans()->pluck('label', 'id'),
|
||||
'availableRegions' => $provider->regions()->pluck('label', 'id'),
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
@@ -12,8 +12,8 @@ class ServiceController extends Controller
|
||||
public function index()
|
||||
{
|
||||
return inertia('Admin/Services/Index', [
|
||||
'servers' => Server::withCount('sites')->latest()->paginate(5, ['*'], 'servers_per_page'),
|
||||
'sites' => Site::with('server:id,name')->latest()->paginate(5, ['*'], 'sites_per_page'),
|
||||
'servers' => Server::query()->withCount('sites', 'users')->latest()->paginate(5, ['*'], 'servers_per_page'),
|
||||
'sites' => Site::with('server:id,name')->withCount('users')->latest()->paginate(5, ['*'], 'sites_per_page'),
|
||||
'providers' => Provider::query()
|
||||
->withCount('regions', 'plans', 'servers')
|
||||
->latest()
|
||||
|
||||
@@ -3,7 +3,10 @@
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Models\Package;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Str;
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use App\Http\Requests\Admin\SettingRequest;
|
||||
|
||||
class SettingController extends Controller
|
||||
@@ -54,11 +57,73 @@ class SettingController extends Controller
|
||||
$value = encrypt($value);
|
||||
}
|
||||
|
||||
if ($key === 'default_package' && $value === 'false') {
|
||||
$value = null;
|
||||
}
|
||||
|
||||
if ($value === 'false') {
|
||||
$value = 0;
|
||||
}
|
||||
|
||||
if ($value === 'true') {
|
||||
$value = 1;
|
||||
}
|
||||
|
||||
setting([$key => $value]);
|
||||
}
|
||||
|
||||
if ($logo = $request->file('logo')) {
|
||||
// If we previously had a logo, rotate that
|
||||
if ($oldLogo = setting('logo')) {
|
||||
Storage::delete(str_replace('/storage/', '/public/', $oldLogo));
|
||||
}
|
||||
|
||||
$version = Str::random();
|
||||
|
||||
$request->file('logo')->storePubliclyAs('logo', 'logo-' . $version . '.' . $request->file('logo')->extension(), 'public');
|
||||
setting(['logo' => '/storage/logo/logo-' . $version . '.' . $request->file('logo')->extension()]);
|
||||
}
|
||||
|
||||
cache()->forget('core.settings');
|
||||
|
||||
return redirect()->route('admin.settings')->with('success', __('Settings have been updated'));
|
||||
}
|
||||
|
||||
public function terms()
|
||||
{
|
||||
return inertia('Admin/Terms', [
|
||||
'settings' => [
|
||||
'logo' => setting('logo'),
|
||||
'name' => setting('name'),
|
||||
'terms_required' => setting('accept_terms_required'),
|
||||
'terms' => setting('terms'),
|
||||
'privacy' => setting('privacy')
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
public function updateTerms(Request $request)
|
||||
{
|
||||
setting(['accept_terms_required' => $request->input('terms_required'),]);
|
||||
setting(['terms' => $request->input('terms'),]);
|
||||
setting(['privacy' => $request->input('privacy'),]);
|
||||
|
||||
return redirect()->route('admin.settings.terms')->with('success', __('Terms have been updated'));
|
||||
}
|
||||
|
||||
public function termsTemplate(Request $request)
|
||||
{
|
||||
$template = file_get_contents(storage_path('templates/terms-of-service.md'));
|
||||
$template = str_replace([
|
||||
'{NAME}',
|
||||
'{WEBSITE}',
|
||||
'{DATE}'
|
||||
], [
|
||||
setting('name'),
|
||||
config('app.url'),
|
||||
date('Y-m-d')
|
||||
], $template);
|
||||
|
||||
return ['content' => $template];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,15 +11,15 @@ class SynchronizeProviderController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
if (config('app.demo')) {
|
||||
if ($this->isDemo()) {
|
||||
return redirect('/')->with('info', __('This feature is not available in demo mode.'));
|
||||
}
|
||||
|
||||
$ploi = new Ploi(config('services.ploi.token'));
|
||||
$availableProviders = $this->getPloi()->user()->serverProviders()->getData();
|
||||
|
||||
$availableProviders = $ploi->user()->serverProviders()->getData();
|
||||
|
||||
$currentProviders = Provider::whereNotIn('id', array_keys((array)$availableProviders))->get();
|
||||
$currentProviders = Provider::query()
|
||||
->whereNotIn('id', array_keys((array)$availableProviders))
|
||||
->get();
|
||||
|
||||
return inertia('Admin/Services/Providers', [
|
||||
'availableProviders' => $availableProviders,
|
||||
@@ -29,7 +29,7 @@ class SynchronizeProviderController extends Controller
|
||||
|
||||
public function synchronize(Request $request, $providerId)
|
||||
{
|
||||
$ploiProvider = (new Ploi)->user()->serverProviders($providerId)->getData();
|
||||
$ploiProvider = $this->getPloi()->user()->serverProviders($providerId)->getData();
|
||||
|
||||
$provider = Provider::updateOrCreate([
|
||||
'ploi_id' => $ploiProvider->id,
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Models\Server;
|
||||
use App\Services\Ploi\Ploi;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Http\Controllers\Controller;
|
||||
|
||||
@@ -11,15 +10,15 @@ class SynchronizeServerController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
if (config('app.demo')) {
|
||||
if ($this->isDemo()) {
|
||||
return redirect('/')->with('info', __('This feature is not available in demo mode.'));
|
||||
}
|
||||
|
||||
$ploi = new Ploi(config('services.ploi.token'));
|
||||
$availableServers = $this->getPloi()->synchronize()->servers()->getData();
|
||||
|
||||
$availableServers = $ploi->synchronize()->servers()->getData();
|
||||
|
||||
$currentServers = Server::whereNotIn('id', array_keys((array)$availableServers))->get();
|
||||
$currentServers = Server::query()
|
||||
->whereNotIn('id', array_keys((array)$availableServers))
|
||||
->get();
|
||||
|
||||
return inertia('Admin/Services/Servers', [
|
||||
'availableServers' => $availableServers,
|
||||
@@ -29,15 +28,37 @@ class SynchronizeServerController extends Controller
|
||||
|
||||
public function synchronizeServer(Request $request)
|
||||
{
|
||||
Server::updateOrCreate([
|
||||
'ploi_id' => $request->input('id')
|
||||
], [
|
||||
'status' => $request->input('status'),
|
||||
'name' => $request->input('name'),
|
||||
'ip' => $request->input('ip_address'),
|
||||
'ssh_port' => $request->input('ssh_port', 22),
|
||||
'internal_ip' => $request->input('internal_ip'),
|
||||
'available_php_versions' => $request->input('installed_php_versions')
|
||||
]);
|
||||
Server::query()
|
||||
->updateOrCreate([
|
||||
'ploi_id' => $request->input('id')
|
||||
], [
|
||||
'status' => $request->input('status'),
|
||||
'name' => $request->input('name'),
|
||||
'ip' => $request->input('ip_address'),
|
||||
'ssh_port' => $request->input('ssh_port', 22),
|
||||
'internal_ip' => $request->input('internal_ip'),
|
||||
'available_php_versions' => $request->input('installed_php_versions')
|
||||
]);
|
||||
}
|
||||
|
||||
public function synchronizeAll(Request $request)
|
||||
{
|
||||
$availableServers = $this->getPloi()->synchronize()->servers()->getData();
|
||||
|
||||
foreach ($availableServers as $availableServer) {
|
||||
Server::query()
|
||||
->updateOrCreate([
|
||||
'ploi_id' => $availableServer->id
|
||||
], [
|
||||
'status' => $availableServer->status,
|
||||
'name' => $availableServer->name,
|
||||
'ip' => $availableServer->ip_address,
|
||||
'ssh_port' => $availableServer->ssh_port,
|
||||
'internal_ip' => $availableServer->internal_ip,
|
||||
'available_php_versions' => $availableServer->installed_php_versions
|
||||
]);
|
||||
}
|
||||
|
||||
return response('ok');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,12 +2,66 @@
|
||||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Models\Site;
|
||||
use App\Models\Server;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Http\Controllers\Controller;
|
||||
|
||||
class SynchronizeSiteController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
return inertia('Admin/Services/Sites');
|
||||
if ($this->isDemo()) {
|
||||
return redirect('/')->with('info', __('This feature is not available in demo mode.'));
|
||||
}
|
||||
|
||||
$availableSites = $this->getPloi()->synchronize()->sites()->getData();
|
||||
|
||||
$currentSites = Site::query()
|
||||
->whereNotIn('id', array_keys((array)$availableSites))
|
||||
->get();
|
||||
|
||||
return inertia('Admin/Services/Sites', [
|
||||
'availableSites' => $availableSites,
|
||||
'currentSites' => $currentSites
|
||||
]);
|
||||
}
|
||||
|
||||
public function synchronizeSite(Request $request)
|
||||
{
|
||||
$server = Server::query()->where('ploi_id', $request->input('server_id'))->firstOrFail();
|
||||
|
||||
$site = Site::query()
|
||||
->updateOrCreate([
|
||||
'ploi_id' => $request->input('id')
|
||||
], [
|
||||
'domain' => $request->input('domain'),
|
||||
'php_version' => $request->input('php_version'),
|
||||
]);
|
||||
|
||||
$site->status = $request->input('status');
|
||||
$site->server_id = $server->id;
|
||||
$site->save();
|
||||
}
|
||||
|
||||
public function synchronizeAll(Request $request)
|
||||
{
|
||||
$availableSites = $this->getPloi()->synchronize()->sites()->getData();
|
||||
|
||||
foreach ($availableSites as $availableSite) {
|
||||
$server = Server::query()->where('ploi_id', $availableSite->server_id)->firstOrFail();
|
||||
|
||||
$site = Site::query()
|
||||
->updateOrCreate([
|
||||
'ploi_id' => $availableSite->server_id
|
||||
], [
|
||||
'domain' => $availableSite->domain,
|
||||
'php_version' => $availableSite->php_version,
|
||||
]);
|
||||
|
||||
$site->status = $availableSite->status;
|
||||
$site->server_id = $server->id;
|
||||
$site->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,10 +6,11 @@ use Illuminate\Http\Request;
|
||||
use App\Jobs\Core\UpdateSystem;
|
||||
use App\Services\VersionChecker;
|
||||
use App\Http\Controllers\Controller;
|
||||
use Laravel\Horizon\Contracts\MasterSupervisorRepository;
|
||||
|
||||
class SystemController extends Controller
|
||||
{
|
||||
public function index()
|
||||
public function index(MasterSupervisorRepository $masterSupervisorRepository)
|
||||
{
|
||||
if (config('app.demo')) {
|
||||
return redirect('/')->with('info', __('This feature is not available in demo mode.'));
|
||||
@@ -17,12 +18,18 @@ class SystemController extends Controller
|
||||
|
||||
$version = (new VersionChecker)->getVersions();
|
||||
|
||||
$horizonRunning = true;
|
||||
if (!$masterSupervisorRepository->all()) {
|
||||
$horizonRunning = false;
|
||||
}
|
||||
|
||||
return inertia('Admin/System', [
|
||||
'version' => [
|
||||
'out_of_date' => $version->isOutOfDate(),
|
||||
'current' => $version->currentVersion,
|
||||
'remote' => $version->remoteVersion
|
||||
]
|
||||
],
|
||||
'horizonRunning' => $horizonRunning
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
@@ -45,8 +45,8 @@ class UserController extends Controller
|
||||
$user->save();
|
||||
}
|
||||
|
||||
if ($package = $request->input('package')) {
|
||||
$user->package_id = $package;
|
||||
if ($request->input('package') && Package::find($request->input('package'))) {
|
||||
$user->package_id = $request->input('package');
|
||||
$user->save();
|
||||
}
|
||||
|
||||
@@ -55,7 +55,17 @@ class UserController extends Controller
|
||||
|
||||
public function show($id)
|
||||
{
|
||||
// TODO: Implement show feature for a user
|
||||
$user = User::query()->findOrFail($id);
|
||||
|
||||
$servers = $user->servers()->withCount('sites')->latest()->paginate(5, ['*'], 'page_servers');
|
||||
|
||||
$sites = $user->sites()->with('server:id,name')->latest()->paginate(5, ['*'], 'page_sites');
|
||||
|
||||
return inertia('Admin/Users/Show', [
|
||||
'user' => $user,
|
||||
'sites' => $sites,
|
||||
'servers' => $servers,
|
||||
]);
|
||||
}
|
||||
|
||||
public function edit($id)
|
||||
|
||||
@@ -7,6 +7,7 @@ use Illuminate\Http\Request;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Providers\RouteServiceProvider;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Validation\Rules\Password;
|
||||
use Illuminate\Foundation\Auth\RegistersUsers;
|
||||
|
||||
class RegisterController extends Controller
|
||||
@@ -27,11 +28,27 @@ class RegisterController extends Controller
|
||||
|
||||
protected function validator(array $data)
|
||||
{
|
||||
return Validator::make($data, [
|
||||
$rules = [
|
||||
'name' => ['required', 'string', 'max:255'],
|
||||
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
|
||||
'password' => ['required', 'string', 'min:8', 'confirmed'],
|
||||
]);
|
||||
'password' => [
|
||||
'required',
|
||||
'string',
|
||||
'confirmed',
|
||||
Password::min(6)
|
||||
->letters()
|
||||
->numbers()
|
||||
->uncompromised()
|
||||
],
|
||||
];
|
||||
|
||||
if (setting('accept_terms_required')) {
|
||||
$rules['terms'] = [
|
||||
'accepted'
|
||||
];
|
||||
}
|
||||
|
||||
return Validator::make($data, $rules);
|
||||
}
|
||||
|
||||
protected function create(array $data)
|
||||
@@ -45,8 +62,8 @@ class RegisterController extends Controller
|
||||
|
||||
protected function registered(Request $request, $user)
|
||||
{
|
||||
if ($defaultPackage = setting('default_package')) {
|
||||
$user->package_id = $defaultPackage;
|
||||
if (setting('default_package') && setting('default_package') != 'false') {
|
||||
$user->package_id = setting('default_package');
|
||||
$user->save();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,11 +2,17 @@
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Traits\HasPloi;
|
||||
use Illuminate\Routing\Controller as BaseController;
|
||||
use Illuminate\Foundation\Validation\ValidatesRequests;
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
|
||||
class Controller extends BaseController
|
||||
{
|
||||
use ValidatesRequests, AuthorizesRequests;
|
||||
use ValidatesRequests, AuthorizesRequests, HasPloi;
|
||||
|
||||
protected function isDemo()
|
||||
{
|
||||
return config('app.demo');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,17 +2,43 @@
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Support\Str;
|
||||
use App\Models\DocumentationItem;
|
||||
use App\Http\Resources\DocumentationItemResource;
|
||||
use App\Models\DocumentationCategory;
|
||||
use App\Http\Resources\DocumentationCategoryRouteResource;
|
||||
|
||||
class DocumentationController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
$documentationItems = DocumentationItem::latest()->paginate();
|
||||
$items = DocumentationCategory::query()->oldest()->get();
|
||||
|
||||
return inertia('Documentation/Index', [
|
||||
'items' => DocumentationItemResource::collection($documentationItems)
|
||||
'items' => DocumentationCategoryRouteResource::collection($items)
|
||||
]);
|
||||
}
|
||||
|
||||
public function show(DocumentationCategory $documentationCategory)
|
||||
{
|
||||
$items = DocumentationCategory::query()->oldest()->get();
|
||||
|
||||
return inertia('Documentation/Show', [
|
||||
'category' => $documentationCategory,
|
||||
'articles' => $documentationCategory->items()->latest()->get(),
|
||||
'items' => DocumentationCategoryRouteResource::collection($items)
|
||||
]);
|
||||
}
|
||||
|
||||
public function showArticle(DocumentationCategory $documentationCategory, DocumentationItem $documentationItem)
|
||||
{
|
||||
$items = DocumentationCategory::query()->oldest()->get();
|
||||
|
||||
$documentationItem->content = Str::markdown($documentationItem->content);
|
||||
|
||||
return inertia('Documentation/Article', [
|
||||
'category' => $documentationCategory,
|
||||
'article' => $documentationItem,
|
||||
'items' => DocumentationCategoryRouteResource::collection($items)
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,10 +2,29 @@
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class PageController extends Controller
|
||||
{
|
||||
public function installationIncomplete()
|
||||
{
|
||||
return inertia('Core/InstallationIncomplete');
|
||||
}
|
||||
|
||||
public function show($slug)
|
||||
{
|
||||
if ($slug === 'terms-of-service' && setting('terms')) {
|
||||
return inertia('Pages/Terms', [
|
||||
'content' => Str::markdown(setting('terms'))
|
||||
]);
|
||||
}
|
||||
|
||||
if ($slug === 'privacy-policy' && setting('privacy')) {
|
||||
return inertia('Pages/Privacy', [
|
||||
'content' => Str::markdown(setting('privacy'))
|
||||
]);
|
||||
}
|
||||
|
||||
abort(404);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,11 @@ class ProfileBillingController extends Controller
|
||||
$packages = Package::query()
|
||||
->where(function ($query) {
|
||||
return $query
|
||||
->where('price_monthly', '>', 0)
|
||||
->where(function ($query) {
|
||||
return $query
|
||||
->where('price_monthly', '>', 0)
|
||||
->orWhere('price_yearly', '>', 0);
|
||||
})
|
||||
->whereNotNull('plan_id');
|
||||
})
|
||||
->when($request->input('sortBy.' . $sortByType), function ($query, $value) use ($sortByType) {
|
||||
@@ -53,27 +57,32 @@ class ProfileBillingController extends Controller
|
||||
})
|
||||
->get()
|
||||
->transform(function (Package $package) {
|
||||
$currencies = [
|
||||
Package::CURRENCY_EURO => '€',
|
||||
Package::CURRENCY_USD => '$',
|
||||
Package::CURRENCY_NOK => 'KR ',
|
||||
Package::CURRENCY_CAD => 'CAD $',
|
||||
Package::CURRENCY_AUD => 'AUD $',
|
||||
];
|
||||
$currency = $this->transformCurrency($package->currency);
|
||||
|
||||
$package->price_monthly = ($currencies[$package->currency] ?? '[Unknown currency]') . number_format($package->price_monthly, 2, ',', '.');
|
||||
$package->period = 'monthly';
|
||||
|
||||
if ($package->price_yearly > 0) {
|
||||
$package->period = 'yearly';
|
||||
}
|
||||
|
||||
$package->price_monthly = ($currency ?? '[Unknown currency]') . number_format($package->price_monthly, 2, ',', '.');
|
||||
$package->price_yearly = ($currency ?? '[Unknown currency]') . number_format($package->price_yearly, 2, ',', '.');
|
||||
|
||||
return $package;
|
||||
});
|
||||
|
||||
try {
|
||||
$clientSecret = $user->createSetupIntent()->client_secret;
|
||||
} catch (\Exception $exception) {
|
||||
return inertia('Profile/BillingError');
|
||||
}
|
||||
|
||||
return inertia('Profile/Billing', [
|
||||
'packages' => $packages,
|
||||
'countries' => countries(),
|
||||
'subscription' => $user->subscription('default'),
|
||||
'public_key' => config('cashier.key'),
|
||||
'data_client_secret' => function () use ($user) {
|
||||
$intent = $user->createSetupIntent();
|
||||
return $intent->client_secret;
|
||||
},
|
||||
'data_client_secret' => $clientSecret,
|
||||
'card' => [
|
||||
'last_four' => $user->card_last_four,
|
||||
'brand' => $user->card_brand
|
||||
@@ -92,8 +101,14 @@ class ProfileBillingController extends Controller
|
||||
$user = $request->user();
|
||||
|
||||
$user->createOrGetStripeCustomer([
|
||||
'name' => $user->name,
|
||||
'description' => $request->input('billing_details')
|
||||
'name' => $request->input('billing_details.name'),
|
||||
'description' => 'Ploi Core Customer ' . $request->input('billing_details.name'),
|
||||
'address' => [
|
||||
'line1' => $request->input('billing_details.address.line1'),
|
||||
'postal_code' => $request->input('billing_details.address.postal_code'),
|
||||
'city' => $request->input('billing_details.address.city'),
|
||||
'country' => $request->input('billing_details.address.country'),
|
||||
]
|
||||
]);
|
||||
|
||||
foreach ($user->paymentMethods() as $paymentMethod) {
|
||||
@@ -163,7 +178,7 @@ class ProfileBillingController extends Controller
|
||||
public function invoices(Request $request)
|
||||
{
|
||||
return $request->user()->invoices()->map(function ($invoice) {
|
||||
$symbol = $invoice->currency === Package::CURRENCY_EURO ? '€' : '$';
|
||||
$symbol = $this->transformCurrency($invoice->currency);
|
||||
|
||||
return [
|
||||
'id' => $invoice->id,
|
||||
@@ -183,4 +198,20 @@ class ProfileBillingController extends Controller
|
||||
'product' => 'Webhosting'
|
||||
]);
|
||||
}
|
||||
|
||||
protected function transformCurrency($key)
|
||||
{
|
||||
$currencies = [
|
||||
Package::CURRENCY_EURO => '€',
|
||||
Package::CURRENCY_USD => '$',
|
||||
Package::CURRENCY_NOK => 'KR ',
|
||||
Package::CURRENCY_CAD => 'CAD $',
|
||||
Package::CURRENCY_AUD => 'AUD $',
|
||||
Package::CURRENCY_GBP => 'GBP £',
|
||||
Package::CURRENCY_INR => 'INR ₹',
|
||||
Package::CURRENCY_THB => 'THB ',
|
||||
];
|
||||
|
||||
return $currencies[strtolower($key)] ?? '$';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,8 @@ class ProfileController extends Controller
|
||||
public function index()
|
||||
{
|
||||
return inertia('Profile/Index', [
|
||||
'profile' => new UserProfileResource(auth()->user())
|
||||
'profile' => new UserProfileResource(auth()->user()),
|
||||
'countries' => countries()
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -36,4 +37,21 @@ class ProfileController extends Controller
|
||||
|
||||
return $mode;
|
||||
}
|
||||
|
||||
public function destroy(Request $request)
|
||||
{
|
||||
/* @var $user \App\Models\User */
|
||||
$user = $request->user();
|
||||
|
||||
$user->sites()->detach();
|
||||
$user->servers()->detach();
|
||||
$user->supportTicketReplies()->delete();
|
||||
$user->supportTickets()->delete();
|
||||
|
||||
$user->delete();
|
||||
|
||||
auth()->logout();
|
||||
|
||||
return redirect()->route('login');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Profile;
|
||||
|
||||
use App\Models\UserProvider;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\ProfileIntegrationRequest;
|
||||
|
||||
class ProfileIntegrationController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
$providers = auth()->user()->providers()->latest()->get()->map(function ($provider) {
|
||||
return [
|
||||
'id' => $provider->id,
|
||||
'type' => $provider->type,
|
||||
'created_at' => $provider->created_at->format('Y-m-d H:i:s')
|
||||
];
|
||||
});
|
||||
|
||||
return inertia('Profile/Integrations', [
|
||||
'providers' => $providers,
|
||||
]);
|
||||
}
|
||||
|
||||
public function store(ProfileIntegrationRequest $request)
|
||||
{
|
||||
$request->user()->providers()->updateOrCreate([
|
||||
'type' => UserProvider::TYPE_CLOUDFLARE
|
||||
], [
|
||||
'type' => UserProvider::TYPE_CLOUDFLARE,
|
||||
'token' => $request->input('meta.api_key'),
|
||||
'meta' => [
|
||||
'cloudflare_email' => encrypt($request->input('meta.cloudflare_email'))
|
||||
]
|
||||
]);
|
||||
|
||||
return redirect()->route('profile.integrations.index');
|
||||
}
|
||||
|
||||
public function destroy($providerId)
|
||||
{
|
||||
auth()->user()->providers()->findOrFail($providerId)->delete();
|
||||
|
||||
return redirect()->route('profile.integrations.index');
|
||||
}
|
||||
}
|
||||
@@ -104,9 +104,21 @@ class ServerController extends Controller
|
||||
{
|
||||
$provider = $request->user()->package->providers()->findOrFail($providerId);
|
||||
|
||||
$regions = $provider->regions()
|
||||
->when($provider->allowed_regions, function ($query) use ($provider) {
|
||||
return $query->whereIn('id', $provider->allowed_regions);
|
||||
})
|
||||
->pluck('label', 'id');
|
||||
|
||||
$plans = $provider->plans()
|
||||
->when($provider->allowed_plans, function ($query) use ($provider) {
|
||||
return $query->whereIn('id', $provider->allowed_plans);
|
||||
})
|
||||
->pluck('label', 'id');
|
||||
|
||||
return [
|
||||
'regions' => $provider->regions()->pluck('label', 'id'),
|
||||
'plans' => $provider->plans()->pluck('label', 'id'),
|
||||
'regions' => $regions,
|
||||
'plans' => $plans,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,9 @@ class SiteCertificateController extends Controller
|
||||
|
||||
$certificate = $site->certificates()->create([
|
||||
'domain' => $request->input('domain'),
|
||||
'type' => $request->input('type', 'letsencrypt'),
|
||||
'certificate' => $request->input('certificate'),
|
||||
'private' => $request->input('private')
|
||||
]);
|
||||
|
||||
$certificate->server_id = $site->server_id;
|
||||
|
||||
@@ -37,7 +37,18 @@ class SiteController extends Controller
|
||||
$server = $request->user()->servers()->findOrFail($serverId);
|
||||
} else {
|
||||
$server = Server::query()
|
||||
->doesntHave('users')
|
||||
->where('maximum_sites', '>', 0)
|
||||
->where(function ($query) {
|
||||
return $query
|
||||
->where(function ($query) {
|
||||
return $query->whereHas('users', function ($query) {
|
||||
return $query->where('user_id', auth()->id());
|
||||
});
|
||||
})
|
||||
->orWhere(function ($query) {
|
||||
return $query->doesntHave('users');
|
||||
});
|
||||
})
|
||||
->withCount('sites')
|
||||
->inRandomOrder()
|
||||
->first();
|
||||
|
||||
@@ -2,7 +2,12 @@
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Site;
|
||||
use Illuminate\Support\Arr;
|
||||
use App\Models\UserProvider;
|
||||
use App\Services\Cloudflare;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Http\Requests\SiteDnsRequest;
|
||||
|
||||
class SiteDnsController extends Controller
|
||||
{
|
||||
@@ -16,9 +21,18 @@ class SiteDnsController extends Controller
|
||||
]);
|
||||
}
|
||||
|
||||
public function store(Request $request)
|
||||
public function store(SiteDnsRequest $request, $id)
|
||||
{
|
||||
//
|
||||
$site = auth()->user()->sites()->findOrFail($id);
|
||||
|
||||
$dns = $this->getDnsInstance($site);
|
||||
|
||||
$dns->addRecord(
|
||||
$request->input('name'),
|
||||
$request->input('address'),
|
||||
);
|
||||
|
||||
return redirect()->route('sites.dns.index', $id)->with('success', __('DNS record has been created'));
|
||||
}
|
||||
|
||||
public function update(Request $request, $id)
|
||||
@@ -28,10 +42,31 @@ class SiteDnsController extends Controller
|
||||
|
||||
public function records($id)
|
||||
{
|
||||
$site = auth()->user()->sites()->findOrFail($id);
|
||||
|
||||
$dns = $this->getDnsInstance($site);
|
||||
|
||||
return $dns->listRecords();
|
||||
}
|
||||
|
||||
public function destroy($id)
|
||||
public function destroy($id, $recordId)
|
||||
{
|
||||
//
|
||||
$site = auth()->user()->sites()->findOrFail($id);
|
||||
|
||||
$dns = $this->getDnsInstance($site);
|
||||
|
||||
$dns->deleteRecord($recordId);
|
||||
|
||||
return redirect()->route('sites.dns.index', $id)->with('success', __('DNS record has been removed'));
|
||||
}
|
||||
|
||||
private function getDnsInstance(Site $site)
|
||||
{
|
||||
$provider = auth()->user()->providers()->where('type', UserProvider::TYPE_CLOUDFLARE)->first();
|
||||
|
||||
$cloudflare = new Cloudflare(decrypt(Arr::get($provider->meta, 'cloudflare_email')), decrypt($provider->token));
|
||||
$cloudflare->zone(decrypt($site->dns_id));
|
||||
|
||||
return $cloudflare;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,6 +68,7 @@ class Kernel extends HttpKernel
|
||||
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
|
||||
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
|
||||
'can' => \Illuminate\Auth\Middleware\Authorize::class,
|
||||
'has.access' => \App\Http\Middleware\HasAccessToThisGroup::class,
|
||||
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
|
||||
'global.api.authenticated' => \App\Http\Middleware\GlobalApiAuthenticated::class,
|
||||
'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
|
||||
|
||||
@@ -10,7 +10,7 @@ class Demo
|
||||
protected $safeRoutes = [
|
||||
'login',
|
||||
'logout',
|
||||
//'profile/toggle-theme'
|
||||
'profile/toggle-theme'
|
||||
];
|
||||
|
||||
protected $allowedIps = [
|
||||
|
||||
@@ -2,8 +2,10 @@
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use App\Models\Alert;
|
||||
use Inertia\Middleware;
|
||||
use Illuminate\Support\Arr;
|
||||
use App\Models\UserProvider;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
@@ -14,7 +16,7 @@ class HandleInertiaRequests extends Middleware
|
||||
* Determines the current asset version.
|
||||
*
|
||||
* @see https://inertiajs.com/asset-versioning
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return string|null
|
||||
*/
|
||||
public function version(Request $request)
|
||||
@@ -26,7 +28,7 @@ class HandleInertiaRequests extends Middleware
|
||||
* Defines the props that are shared by default.
|
||||
*
|
||||
* @see https://inertiajs.com/shared-data
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return array
|
||||
*/
|
||||
public function share(Request $request)
|
||||
@@ -59,6 +61,10 @@ class HandleInertiaRequests extends Middleware
|
||||
'theme' => Auth::user()->theme,
|
||||
'keyboard_shortcuts' => Auth::user()->keyboard_shortcuts,
|
||||
'requires_password_for_ftp' => Auth::user()->requires_password_for_ftp,
|
||||
'address' => Auth::user()->address,
|
||||
'country' => Auth::user()->country,
|
||||
'zip' => Auth::user()->zip,
|
||||
'city' => Auth::user()->city,
|
||||
] : null,
|
||||
'package' => auth()->user() && auth()->user()->package ? [
|
||||
'name' => auth()->user()->package->name,
|
||||
@@ -66,7 +72,10 @@ class HandleInertiaRequests extends Middleware
|
||||
] : [
|
||||
'name' => __('None')
|
||||
],
|
||||
'can' => $can
|
||||
'can' => $can,
|
||||
'integrations' => [
|
||||
'cloudflare' => (bool)auth()->user() ? auth()->user()->providers()->where('type', UserProvider::TYPE_CLOUDFLARE)->count() : false,
|
||||
]
|
||||
];
|
||||
},
|
||||
|
||||
@@ -78,7 +87,10 @@ class HandleInertiaRequests extends Middleware
|
||||
'documentation' => setting('documentation', false),
|
||||
'logo' => setting('logo'),
|
||||
'allow_registration' => setting('allow_registration'),
|
||||
'billing' => config('cashier.key') && config('cashier.secret')
|
||||
'billing' => config('cashier.key') && config('cashier.secret'),
|
||||
'has_terms' => (bool)setting('terms'),
|
||||
'has_privacy' => (bool)setting('privacy'),
|
||||
'accept_terms_required' => (bool)setting('accept_terms_required')
|
||||
];
|
||||
},
|
||||
'flash' => function () {
|
||||
@@ -98,6 +110,24 @@ class HandleInertiaRequests extends Middleware
|
||||
? count(Session::get('errors')->getBag('default')->getMessages())
|
||||
: 0;
|
||||
},
|
||||
'system_alert' => function () {
|
||||
$alert = Alert::query()
|
||||
->where(function ($query) {
|
||||
return $query
|
||||
->whereNull('expires_at')
|
||||
->orWhere('expires_at', '>', now());
|
||||
})
|
||||
->first(['message', 'expires_at', 'type']);
|
||||
|
||||
if (!$alert) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return [
|
||||
'message' => $alert->message,
|
||||
'type' => $alert->type
|
||||
];
|
||||
}
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
27
app/Http/Middleware/HasAccessToThisGroup.php
Normal file
27
app/Http/Middleware/HasAccessToThisGroup.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Arr;
|
||||
|
||||
class HasAccessToThisGroup
|
||||
{
|
||||
public function handle(Request $request, Closure $next, $group)
|
||||
{
|
||||
if ($group === 'servers') {
|
||||
$package = $request->user()->package ?? [];
|
||||
|
||||
if (
|
||||
!Arr::get($package->server_permissions, 'create', false) &&
|
||||
!Arr::get($package->server_permissions, 'update', false) &&
|
||||
!Arr::get($package->server_permissions, 'delete', false)
|
||||
) {
|
||||
abort(404);
|
||||
}
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
50
app/Http/Requests/Admin/AlertRequest.php
Normal file
50
app/Http/Requests/Admin/AlertRequest.php
Normal file
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests\Admin;
|
||||
|
||||
use App\Models\Alert;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class AlertRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return auth()->check() && auth()->user()->isAdmin();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'message' => [
|
||||
'required',
|
||||
'string',
|
||||
'max:500'
|
||||
],
|
||||
'type' => [
|
||||
'required',
|
||||
'string',
|
||||
Rule::in([
|
||||
Alert::TYPE_INFO,
|
||||
Alert::TYPE_DANGER,
|
||||
Alert::TYPE_WARNING
|
||||
])
|
||||
],
|
||||
'expires_at' => [
|
||||
'nullable',
|
||||
'date',
|
||||
'date_format:Y-m-d H:i:s'
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -39,6 +39,9 @@ class PackageRequest extends FormRequest
|
||||
Package::CURRENCY_NOK,
|
||||
Package::CURRENCY_AUD,
|
||||
Package::CURRENCY_CAD,
|
||||
Package::CURRENCY_GBP,
|
||||
Package::CURRENCY_INR,
|
||||
Package::CURRENCY_THB,
|
||||
])
|
||||
],
|
||||
'maximum_sites' => [
|
||||
@@ -56,7 +59,11 @@ class PackageRequest extends FormRequest
|
||||
],
|
||||
'price_monthly' => [
|
||||
'nullable',
|
||||
'numeric'
|
||||
'numeric',
|
||||
],
|
||||
'price_yearly' => [
|
||||
'nullable',
|
||||
'numeric',
|
||||
],
|
||||
'server_permissions' => [
|
||||
'array'
|
||||
@@ -76,8 +83,12 @@ class PackageRequest extends FormRequest
|
||||
$merge['price_monthly'] = 0.000;
|
||||
}
|
||||
|
||||
if (!$this->price_yearly) {
|
||||
$merge['price_yearly'] = 0.000;
|
||||
}
|
||||
|
||||
// If we don't have the currency filled in, merge a default
|
||||
if (!$this->price_monthly) {
|
||||
if (!$this->price_monthly || !$this->price_yearly) {
|
||||
$merge['currency'] = Package::CURRENCY_USD;
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,14 @@ class ProviderRequest extends FormRequest
|
||||
'required',
|
||||
'string',
|
||||
'max:255'
|
||||
],
|
||||
'allowed_plans' => [
|
||||
'nullable',
|
||||
'array'
|
||||
],
|
||||
'allowed_regions' => [
|
||||
'nullable',
|
||||
'array'
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
@@ -33,6 +33,12 @@ class SettingRequest extends FormRequest
|
||||
'email' => [
|
||||
'nullable',
|
||||
'email'
|
||||
],
|
||||
|
||||
'logo' => [
|
||||
'nullable',
|
||||
'image',
|
||||
'max:2000'
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
63
app/Http/Requests/ProfileIntegrationRequest.php
Normal file
63
app/Http/Requests/ProfileIntegrationRequest.php
Normal file
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use App\Models\UserProvider;
|
||||
use Illuminate\Validation\Rule;
|
||||
use App\Rules\CloudflareGeneralTest;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class ProfileIntegrationRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return auth()->check();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
$rules = [
|
||||
'provider' => [
|
||||
'required',
|
||||
'string',
|
||||
Rule::in([
|
||||
UserProvider::TYPE_CLOUDFLARE
|
||||
])
|
||||
]
|
||||
];
|
||||
|
||||
if ($this->input('provider') === UserProvider::TYPE_CLOUDFLARE) {
|
||||
$rules['meta.api_key'] = [
|
||||
'required',
|
||||
'string',
|
||||
new CloudflareGeneralTest($this->input('meta.cloudflare_email'))
|
||||
];
|
||||
|
||||
$rules['meta.cloudflare_email'] = [
|
||||
'required',
|
||||
'string',
|
||||
'email'
|
||||
];
|
||||
}
|
||||
|
||||
return $rules;
|
||||
}
|
||||
|
||||
public function messages()
|
||||
{
|
||||
return [
|
||||
'meta.api_key.required' => __('The API key field is required'),
|
||||
'meta.cloudflare_email.required' => __('The Cloudflare email field is required'),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -25,15 +25,36 @@ class SiteCertificateRequest extends FormRequest
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'domain' => [
|
||||
'required',
|
||||
'string',
|
||||
Rule::unique('certificates', 'domain')->where(function ($query) {
|
||||
return $query->where('site_id', $this->route('site'));
|
||||
}),
|
||||
new LetsEncryptMatchHostWithIp($this->route('site'))
|
||||
]
|
||||
];
|
||||
$rules = [];
|
||||
|
||||
if ($this->input('type') === 'letsencrypt') {
|
||||
$rules = [
|
||||
'domain' => [
|
||||
'required',
|
||||
'string',
|
||||
Rule::unique('certificates', 'domain')->where(function ($query) {
|
||||
return $query->where('site_id', $this->route('site'));
|
||||
}),
|
||||
new LetsEncryptMatchHostWithIp($this->route('site'))
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
if ($this->input('type') === 'custom') {
|
||||
$rules = [
|
||||
'certificate' => [
|
||||
'required',
|
||||
'string',
|
||||
'min:5'
|
||||
],
|
||||
'private' => [
|
||||
'required',
|
||||
'string',
|
||||
'min:5'
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
return $rules;
|
||||
}
|
||||
}
|
||||
|
||||
37
app/Http/Requests/SiteDnsRequest.php
Normal file
37
app/Http/Requests/SiteDnsRequest.php
Normal file
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class SiteDnsRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return auth()->check();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
return [
|
||||
'name' => [
|
||||
'required',
|
||||
'string',
|
||||
],
|
||||
'address' => [
|
||||
'required',
|
||||
'ipv4'
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -41,6 +41,22 @@ class UserProfileRequest extends FormRequest
|
||||
'required',
|
||||
'string',
|
||||
Rule::in(languages()),
|
||||
],
|
||||
'address' => [
|
||||
'nullable',
|
||||
'string'
|
||||
],
|
||||
'country' => [
|
||||
'nullable',
|
||||
'string'
|
||||
],
|
||||
'zip' => [
|
||||
'nullable',
|
||||
'string'
|
||||
],
|
||||
'city' => [
|
||||
'nullable',
|
||||
'string'
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
23
app/Http/Resources/DocumentationCategoryRouteResource.php
Normal file
23
app/Http/Resources/DocumentationCategoryRouteResource.php
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Resources;
|
||||
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class DocumentationCategoryRouteResource extends JsonResource
|
||||
{
|
||||
/**
|
||||
* Transform the resource into an array.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return array
|
||||
*/
|
||||
public function toArray($request)
|
||||
{
|
||||
return [
|
||||
'title' => $this->title,
|
||||
'to' => route('documentation.show', $this->id),
|
||||
'active' => object_get(request()->route('documentationCategory'), 'id') === $this->id ? true : false
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -19,7 +19,11 @@ class UserProfileResource extends JsonResource
|
||||
return [
|
||||
'name' => $this->name,
|
||||
'email' => $this->email,
|
||||
'language' => $this->language
|
||||
'language' => $this->language,
|
||||
'address' => $this->address,
|
||||
'country' => $this->country,
|
||||
'zip' => $this->zip,
|
||||
'city' => $this->city
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace App\Jobs\Apps;
|
||||
|
||||
use App\Models\Site;
|
||||
use App\Services\Ploi\Ploi;
|
||||
use App\Traits\HasPloi;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
@@ -12,9 +13,9 @@ use Illuminate\Foundation\Bus\Dispatchable;
|
||||
|
||||
class InstallApp implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels, HasPloi;
|
||||
|
||||
public $site;
|
||||
public Site $site;
|
||||
public $type;
|
||||
public $options;
|
||||
|
||||
@@ -25,7 +26,7 @@ class InstallApp implements ShouldQueue
|
||||
* @param string $type
|
||||
* @param array $options
|
||||
*/
|
||||
public function __construct(Site $site, $type = Site::PROJECT_WORDPRESS, array $options = [])
|
||||
public function __construct(Site $site, string $type = Site::PROJECT_WORDPRESS, array $options = [])
|
||||
{
|
||||
$this->site = $site;
|
||||
$this->type = $type;
|
||||
@@ -39,8 +40,10 @@ class InstallApp implements ShouldQueue
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$ploi = new Ploi(config('services.ploi.token'));
|
||||
|
||||
$ploi->server($this->site->server->ploi_id)->sites($this->site->ploi_id)->app()->install($this->type, $this->options);
|
||||
$this->getPloi()
|
||||
->server($this->site->server->ploi_id)
|
||||
->sites($this->site->ploi_id)
|
||||
->app()
|
||||
->install($this->type, $this->options);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace App\Jobs\Apps;
|
||||
|
||||
use App\Models\Site;
|
||||
use App\Services\Ploi\Ploi;
|
||||
use App\Traits\HasPloi;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
@@ -12,9 +13,9 @@ use Illuminate\Foundation\Bus\Dispatchable;
|
||||
|
||||
class UninstallApp implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels, HasPloi;
|
||||
|
||||
public $site;
|
||||
public Site $site;
|
||||
|
||||
/**
|
||||
* Create a new job instance.
|
||||
@@ -37,9 +38,11 @@ class UninstallApp implements ShouldQueue
|
||||
return;
|
||||
}
|
||||
|
||||
$ploi = new Ploi(config('services.ploi.token'));
|
||||
|
||||
$ploi->server($this->site->server->ploi_id)->sites($this->site->ploi_id)->app()->uninstall($this->site->project);
|
||||
$this->getPloi()
|
||||
->server($this->site->server->ploi_id)
|
||||
->sites($this->site->ploi_id)
|
||||
->app()
|
||||
->uninstall($this->site->project);
|
||||
|
||||
$this->site->project = null;
|
||||
$this->site->save();
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace App\Jobs\Certificates;
|
||||
|
||||
use App\Models\Certificate;
|
||||
use App\Services\Ploi\Ploi;
|
||||
use App\Traits\HasPloi;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
@@ -12,38 +13,44 @@ use Illuminate\Foundation\Bus\Dispatchable;
|
||||
|
||||
class CreateCertificate implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels, HasPloi;
|
||||
|
||||
public $certificate;
|
||||
public Certificate $certificate;
|
||||
|
||||
/**
|
||||
* Create a new job instance.
|
||||
*
|
||||
* @param Certificate $certificate
|
||||
*/
|
||||
public function __construct(Certificate $certificate)
|
||||
{
|
||||
$this->certificate = $certificate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the job.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$ploi = new Ploi(config('services.ploi.token'));
|
||||
if ($this->certificate->type === 'letsencrypt') {
|
||||
$ploiCertificate = $this->getPloi()
|
||||
->server($this->certificate->server->ploi_id)
|
||||
->sites($this->certificate->site->ploi_id)
|
||||
->certificates()
|
||||
->create(
|
||||
$this->certificate->domain
|
||||
);
|
||||
|
||||
$ploiCertificate = $ploi->server($this->certificate->server->ploi_id)
|
||||
->sites($this->certificate->site->ploi_id)
|
||||
->certificates()
|
||||
->create(
|
||||
$this->certificate->domain
|
||||
);
|
||||
$this->certificate->ploi_id = $ploiCertificate->id;
|
||||
$this->certificate->save();
|
||||
}
|
||||
|
||||
$this->certificate->ploi_id = $ploiCertificate->id;
|
||||
$this->certificate->save();
|
||||
if ($this->certificate->type === 'custom') {
|
||||
$ploiCertificate = $this->getPloi()
|
||||
->server($this->certificate->server->ploi_id)
|
||||
->sites($this->certificate->site->ploi_id)
|
||||
->certificates()
|
||||
->create(
|
||||
$this->certificate->certificate,
|
||||
$this->certificate->type,
|
||||
$this->certificate->private
|
||||
);
|
||||
|
||||
$this->certificate->ploi_id = $ploiCertificate->id;
|
||||
$this->certificate->save();
|
||||
}
|
||||
|
||||
// Lets fetch the status after 5 seconds
|
||||
dispatch(new FetchCertificateStatus($this->certificate))->delay(now()->addSeconds(5));
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
namespace App\Jobs\Certificates;
|
||||
|
||||
use App\Services\Ploi\Ploi;
|
||||
use App\Traits\HasPloi;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
@@ -11,7 +12,7 @@ use Illuminate\Foundation\Bus\Dispatchable;
|
||||
|
||||
class DeleteCertificate implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels, HasPloi;
|
||||
|
||||
public $serverPloiId;
|
||||
public $sitePloiId;
|
||||
@@ -42,9 +43,8 @@ class DeleteCertificate implements ShouldQueue
|
||||
return;
|
||||
}
|
||||
|
||||
$ploi = new Ploi(config('services.ploi.token'));
|
||||
|
||||
$ploi->server($this->serverPloiId)
|
||||
$this->getPloi()
|
||||
->server($this->serverPloiId)
|
||||
->sites($this->sitePloiId)
|
||||
->certificates()
|
||||
->delete($this->certificatePloiId);
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace App\Jobs\Certificates;
|
||||
|
||||
use App\Models\Certificate;
|
||||
use App\Services\Ploi\Ploi;
|
||||
use App\Traits\HasPloi;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use App\Traits\JobHasThresholds;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
@@ -13,7 +14,7 @@ use Illuminate\Foundation\Bus\Dispatchable;
|
||||
|
||||
class FetchCertificateStatus implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels, JobHasThresholds;
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels, JobHasThresholds, HasPloi;
|
||||
|
||||
public $certificate;
|
||||
|
||||
@@ -23,7 +24,7 @@ class FetchCertificateStatus implements ShouldQueue
|
||||
* @param Certificate $certificate
|
||||
* @param int $threshold
|
||||
*/
|
||||
public function __construct(Certificate $certificate, $threshold = 0)
|
||||
public function __construct(Certificate $certificate, int $threshold = 0)
|
||||
{
|
||||
$this->certificate = $certificate;
|
||||
$this->setThreshold($threshold);
|
||||
@@ -43,9 +44,8 @@ class FetchCertificateStatus implements ShouldQueue
|
||||
return;
|
||||
}
|
||||
|
||||
$ploi = new Ploi(config('services.ploi.token'));
|
||||
|
||||
$ploiCronjob = $ploi->server($this->certificate->server->ploi_id)
|
||||
$ploiCronjob = $this->getPloi()
|
||||
->server($this->certificate->server->ploi_id)
|
||||
->sites($this->certificate->site->ploi_id)
|
||||
->certificates()
|
||||
->get($this->certificate->ploi_id)
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace App\Jobs\Core;
|
||||
|
||||
use App\Services\Ploi\Ploi;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use App\Services\VersionChecker;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
@@ -16,21 +17,29 @@ class Ping implements ShouldQueue
|
||||
|
||||
public function handle()
|
||||
{
|
||||
$version = new VersionChecker;
|
||||
|
||||
$version->flushVersionData();
|
||||
|
||||
$response = Http::withHeaders([
|
||||
'Accept' => 'application/json',
|
||||
'Content-Type' => 'application/json',
|
||||
'X-Ploi-Core-Key' => config('services.ploi.core-token')
|
||||
])
|
||||
->withToken(config('services.ploi.token'))
|
||||
->get((new Ploi)->url . 'ping');
|
||||
->post((new Ploi)->url . 'ping', [
|
||||
'version' => $version->getApplicationVersion(),
|
||||
'php_version' => phpversion(),
|
||||
'panel_url' => config('app.url')
|
||||
]);
|
||||
|
||||
if (!$response->ok() || !$response->json()) {
|
||||
|
||||
// Something went wrong..
|
||||
|
||||
return;
|
||||
return 1;
|
||||
}
|
||||
|
||||
$response->json();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace App\Jobs\Cronjobs;
|
||||
|
||||
use App\Models\Cronjob;
|
||||
use App\Services\Ploi\Ploi;
|
||||
use App\Traits\HasPloi;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
@@ -12,7 +13,7 @@ use Illuminate\Foundation\Bus\Dispatchable;
|
||||
|
||||
class CreateCronjob implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels, HasPloi;
|
||||
|
||||
public $cronjob;
|
||||
|
||||
@@ -35,13 +36,14 @@ class CreateCronjob implements ShouldQueue
|
||||
{
|
||||
$owner = $this->cronjob->site->users()->first();
|
||||
|
||||
$ploi = new Ploi(config('services.ploi.token'));
|
||||
|
||||
$ploiCronjob = $ploi->server($this->cronjob->server->ploi_id)->cronjobs()->create(
|
||||
$this->cronjob->command,
|
||||
$this->cronjob->frequency,
|
||||
$owner->user_name
|
||||
);
|
||||
$ploiCronjob = $this->getPloi()
|
||||
->server($this->cronjob->server->ploi_id)
|
||||
->cronjobs()
|
||||
->create(
|
||||
$this->cronjob->command,
|
||||
$this->cronjob->frequency,
|
||||
$owner->user_name
|
||||
);
|
||||
|
||||
$this->cronjob->ploi_id = $ploiCronjob->id;
|
||||
$this->cronjob->save();
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
namespace App\Jobs\Cronjobs;
|
||||
|
||||
use App\Services\Ploi\Ploi;
|
||||
use App\Traits\HasPloi;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
@@ -11,7 +12,7 @@ use Illuminate\Foundation\Bus\Dispatchable;
|
||||
|
||||
class DeleteCronjob implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels, HasPloi;
|
||||
|
||||
public $serverPloiId;
|
||||
public $cronjobPloiId;
|
||||
@@ -39,8 +40,9 @@ class DeleteCronjob implements ShouldQueue
|
||||
return;
|
||||
}
|
||||
|
||||
$ploi = new Ploi(config('services.ploi.token'));
|
||||
|
||||
$ploi->server($this->serverPloiId)->cronjobs()->delete($this->cronjobPloiId);
|
||||
$this->getPloi()
|
||||
->server($this->serverPloiId)
|
||||
->cronjobs()
|
||||
->delete($this->cronjobPloiId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace App\Jobs\Cronjobs;
|
||||
|
||||
use App\Models\Cronjob;
|
||||
use App\Services\Ploi\Ploi;
|
||||
use App\Traits\HasPloi;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use App\Traits\JobHasThresholds;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
@@ -13,7 +14,7 @@ use Illuminate\Foundation\Bus\Dispatchable;
|
||||
|
||||
class FetchCronjobStatus implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels, JobHasThresholds;
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels, JobHasThresholds, HasPloi;
|
||||
|
||||
public $cronjob;
|
||||
|
||||
@@ -23,7 +24,7 @@ class FetchCronjobStatus implements ShouldQueue
|
||||
* @param Cronjob $cronjob
|
||||
* @param int $threshold
|
||||
*/
|
||||
public function __construct(Cronjob $cronjob, $threshold = 0)
|
||||
public function __construct(Cronjob $cronjob, int $threshold = 0)
|
||||
{
|
||||
$this->cronjob = $cronjob;
|
||||
$this->setThreshold($threshold);
|
||||
@@ -43,9 +44,11 @@ class FetchCronjobStatus implements ShouldQueue
|
||||
return;
|
||||
}
|
||||
|
||||
$ploi = new Ploi(config('services.ploi.token'));
|
||||
|
||||
$ploiCronjob = $ploi->server($this->cronjob->server->ploi_id)->cronjobs()->get($this->cronjob->ploi_id)->getData();
|
||||
$ploiCronjob = $this->getPloi()
|
||||
->server($this->cronjob->server->ploi_id)
|
||||
->cronjobs()
|
||||
->get($this->cronjob->ploi_id)
|
||||
->getData();
|
||||
|
||||
if ($ploiCronjob->status !== Cronjob::STATUS_ACTIVE) {
|
||||
$this->incrementThreshold();
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
namespace App\Jobs\Databases;
|
||||
|
||||
use App\Traits\HasPloi;
|
||||
use App\Models\Database;
|
||||
use App\Services\Ploi\Ploi;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
@@ -12,7 +12,7 @@ use Illuminate\Foundation\Bus\Dispatchable;
|
||||
|
||||
class CreateDatabase implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels, HasPloi;
|
||||
|
||||
public $database;
|
||||
public $password;
|
||||
@@ -38,9 +38,10 @@ class CreateDatabase implements ShouldQueue
|
||||
{
|
||||
$databaseUser = $this->database->users()->first();
|
||||
|
||||
$ploi = new Ploi(config('services.ploi.token'));
|
||||
|
||||
$ploiDatabase = $ploi->server($this->database->server->ploi_id)->databases()->create($this->database->name, $databaseUser->name, $this->password);
|
||||
$ploiDatabase = $this->getPloi()
|
||||
->server($this->database->server->ploi_id)
|
||||
->databases()
|
||||
->create($this->database->name, $databaseUser->name, $this->password);
|
||||
|
||||
$this->database->ploi_id = $ploiDatabase->id;
|
||||
$this->database->save();
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
namespace App\Jobs\Databases;
|
||||
|
||||
use App\Services\Ploi\Ploi;
|
||||
use App\Traits\HasPloi;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
@@ -11,7 +12,7 @@ use Illuminate\Foundation\Bus\Dispatchable;
|
||||
|
||||
class DeleteDatabase implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels, HasPloi;
|
||||
|
||||
public $serverPloiId;
|
||||
public $databasePloiId;
|
||||
@@ -40,8 +41,6 @@ class DeleteDatabase implements ShouldQueue
|
||||
return;
|
||||
}
|
||||
|
||||
$ploi = new Ploi(config('services.ploi.token'));
|
||||
|
||||
$ploi->server($this->serverPloiId)->databases()->delete($this->databasePloiId);
|
||||
$this->getPloi()->server($this->serverPloiId)->databases()->delete($this->databasePloiId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
namespace App\Jobs\Databases;
|
||||
|
||||
use App\Traits\HasPloi;
|
||||
use App\Models\Database;
|
||||
use App\Services\Ploi\Ploi;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use App\Traits\JobHasThresholds;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
@@ -13,7 +13,7 @@ use Illuminate\Foundation\Bus\Dispatchable;
|
||||
|
||||
class FetchDatabaseStatus implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels, JobHasThresholds;
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels, JobHasThresholds, HasPloi;
|
||||
|
||||
public $database;
|
||||
|
||||
@@ -23,7 +23,7 @@ class FetchDatabaseStatus implements ShouldQueue
|
||||
* @param Database $database
|
||||
* @param int $threshold
|
||||
*/
|
||||
public function __construct(Database $database, $threshold = 0)
|
||||
public function __construct(Database $database, int $threshold = 0)
|
||||
{
|
||||
$this->database = $database;
|
||||
$this->setThreshold($threshold);
|
||||
@@ -43,9 +43,11 @@ class FetchDatabaseStatus implements ShouldQueue
|
||||
return;
|
||||
}
|
||||
|
||||
$ploi = new Ploi(config('services.ploi.token'));
|
||||
|
||||
$ploiDatabase = $ploi->server($this->database->server->ploi_id)->databases()->get($this->database->ploi_id)->getData();
|
||||
$ploiDatabase = $this->getPloi()
|
||||
->server($this->database->server->ploi_id)
|
||||
->databases()
|
||||
->get($this->database->ploi_id)
|
||||
->getData();
|
||||
|
||||
if ($ploiDatabase->status !== Database::STATUS_ACTIVE) {
|
||||
$this->incrementThreshold();
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
namespace App\Jobs\Redirects;
|
||||
|
||||
use App\Traits\HasPloi;
|
||||
use App\Models\Redirect;
|
||||
use App\Services\Ploi\Ploi;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
@@ -12,7 +12,7 @@ use Illuminate\Foundation\Bus\Dispatchable;
|
||||
|
||||
class CreateRedirect implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels, HasPloi;
|
||||
|
||||
public $redirect;
|
||||
|
||||
@@ -33,9 +33,7 @@ class CreateRedirect implements ShouldQueue
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$ploi = new Ploi(config('services.ploi.token'));
|
||||
|
||||
$ploiRedirect = $ploi
|
||||
$ploiRedirect = $this->getPloi()
|
||||
->server($this->redirect->server->ploi_id)
|
||||
->sites($this->redirect->site->ploi_id)
|
||||
->redirects()
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
namespace App\Jobs\Redirects;
|
||||
|
||||
use App\Services\Ploi\Ploi;
|
||||
use App\Traits\HasPloi;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
@@ -11,7 +11,7 @@ use Illuminate\Foundation\Bus\Dispatchable;
|
||||
|
||||
class DeleteRedirect implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels, HasPloi;
|
||||
|
||||
public $serverPloiId;
|
||||
public $sitePloiId;
|
||||
@@ -42,9 +42,8 @@ class DeleteRedirect implements ShouldQueue
|
||||
return;
|
||||
}
|
||||
|
||||
$ploi = new Ploi(config('services.ploi.token'));
|
||||
|
||||
$ploi->server($this->serverPloiId)
|
||||
$this->getPloi()
|
||||
->server($this->serverPloiId)
|
||||
->sites($this->sitePloiId)
|
||||
->redirects()
|
||||
->delete($this->redirectPloiId);
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
namespace App\Jobs\Redirects;
|
||||
|
||||
use App\Traits\HasPloi;
|
||||
use App\Models\Redirect;
|
||||
use App\Services\Ploi\Ploi;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use App\Traits\JobHasThresholds;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
@@ -13,7 +13,7 @@ use Illuminate\Foundation\Bus\Dispatchable;
|
||||
|
||||
class FetchRedirectStatus implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels, JobHasThresholds;
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels, JobHasThresholds, HasPloi;
|
||||
|
||||
public $redirect;
|
||||
|
||||
@@ -23,7 +23,7 @@ class FetchRedirectStatus implements ShouldQueue
|
||||
* @param Redirect $redirect
|
||||
* @param int $threshold
|
||||
*/
|
||||
public function __construct(Redirect $redirect, $threshold = 0)
|
||||
public function __construct(Redirect $redirect, int $threshold = 0)
|
||||
{
|
||||
$this->redirect = $redirect;
|
||||
$this->setThreshold($threshold);
|
||||
@@ -43,9 +43,8 @@ class FetchRedirectStatus implements ShouldQueue
|
||||
return;
|
||||
}
|
||||
|
||||
$ploi = new Ploi(config('services.ploi.token'));
|
||||
|
||||
$ploiRedirect = $ploi->server($this->redirect->server->ploi_id)
|
||||
$ploiRedirect = $this->getPloi()
|
||||
->server($this->redirect->server->ploi_id)
|
||||
->sites($this->redirect->site->ploi_id)
|
||||
->redirects()
|
||||
->get($this->redirect->ploi_id)->getData();
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
namespace App\Jobs\Servers;
|
||||
|
||||
use App\Models\Server;
|
||||
use App\Services\Ploi\Ploi;
|
||||
use App\Traits\HasPloi;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
@@ -12,7 +12,7 @@ use Illuminate\Foundation\Bus\Dispatchable;
|
||||
|
||||
class CreateServer implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels, HasPloi;
|
||||
|
||||
public $server;
|
||||
public $tries = 1;
|
||||
@@ -34,9 +34,7 @@ class CreateServer implements ShouldQueue
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$ploi = new Ploi(config('services.ploi.token'));
|
||||
|
||||
$ploiServer = $ploi->server()->create(
|
||||
$ploiServer = $this->getPloi()->server()->create(
|
||||
$this->server->name,
|
||||
$this->server->provider->ploi_id,
|
||||
$this->server->providerRegion->region_id,
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
namespace App\Jobs\Servers;
|
||||
|
||||
use App\Services\Ploi\Ploi;
|
||||
use App\Traits\HasPloi;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
@@ -11,7 +11,7 @@ use Illuminate\Foundation\Bus\Dispatchable;
|
||||
|
||||
class DeleteServer implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels, HasPloi;
|
||||
|
||||
public $serverPloiId;
|
||||
|
||||
@@ -32,8 +32,6 @@ class DeleteServer implements ShouldQueue
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$ploi = new Ploi(config('services.ploi.token'));
|
||||
|
||||
$ploi->server($this->serverPloiId)->delete();
|
||||
$this->getPloi()->server($this->serverPloiId)->delete();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
namespace App\Jobs\Servers;
|
||||
|
||||
use App\Models\Server;
|
||||
use App\Services\Ploi\Ploi;
|
||||
use App\Traits\HasPloi;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use App\Traits\JobHasThresholds;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
@@ -13,7 +13,7 @@ use Illuminate\Foundation\Bus\Dispatchable;
|
||||
|
||||
class FetchServerStatus implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels, JobHasThresholds;
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels, JobHasThresholds, HasPloi;
|
||||
|
||||
public $server;
|
||||
|
||||
@@ -43,9 +43,7 @@ class FetchServerStatus implements ShouldQueue
|
||||
return;
|
||||
}
|
||||
|
||||
$ploi = new Ploi;
|
||||
|
||||
$ploiServer = $ploi->server($this->server->ploi_id)->get()->getData();
|
||||
$ploiServer = $this->getPloi()->server($this->server->ploi_id)->get()->getData();
|
||||
|
||||
if ($ploiServer->status !== Server::STATUS_ACTIVE) {
|
||||
$this->incrementThreshold();
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Jobs\Servers;
|
||||
|
||||
use App\Models\Server;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
|
||||
class SynchronizeServers implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
|
||||
/**
|
||||
* Execute the job.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$ploi = new \App\Services\Ploi\Ploi(config('services.ploi.token'));
|
||||
|
||||
$servers = $ploi->server()->get()->getData();
|
||||
|
||||
foreach ($servers as $server) {
|
||||
Server::firstOrCreate([
|
||||
'ip' => $server->ip_address,
|
||||
], [
|
||||
'name' => $server->name
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
namespace App\Jobs\Sites;
|
||||
|
||||
use App\Models\Site;
|
||||
use App\Services\Ploi\Ploi;
|
||||
use App\Traits\HasPloi;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
@@ -12,7 +12,7 @@ use Illuminate\Foundation\Bus\Dispatchable;
|
||||
|
||||
class ChangePhpVersion implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels, HasPloi;
|
||||
|
||||
public $site;
|
||||
public $version;
|
||||
@@ -36,9 +36,7 @@ class ChangePhpVersion implements ShouldQueue
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$ploi = new Ploi(config('services.ploi.token'));
|
||||
|
||||
$ploi->server($this->site->server->ploi_id)->sites($this->site->ploi_id)->phpVersion($this->version);
|
||||
$this->getPloi()->server($this->site->server->ploi_id)->sites($this->site->ploi_id)->phpVersion($this->version);
|
||||
|
||||
$this->site->php_version = $this->version;
|
||||
$this->site->save();
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
namespace App\Jobs\Sites;
|
||||
|
||||
use App\Models\Site;
|
||||
use App\Services\Ploi\Ploi;
|
||||
use App\Traits\HasPloi;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
@@ -13,7 +13,7 @@ use Illuminate\Foundation\Bus\Dispatchable;
|
||||
|
||||
class CreateSite implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels, HasPloi;
|
||||
|
||||
public $site;
|
||||
|
||||
@@ -34,11 +34,9 @@ class CreateSite implements ShouldQueue
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$ploi = new Ploi(config('services.ploi.token'));
|
||||
|
||||
$systemUser = $this->site->getSystemUser();
|
||||
|
||||
$ploiSite = $ploi->server($this->site->server->ploi_id)->sites()->create(
|
||||
$ploiSite = $this->getPloi()->server($this->site->server->ploi_id)->sites()->create(
|
||||
$this->site->domain,
|
||||
'/public',
|
||||
'/',
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
namespace App\Jobs\Sites;
|
||||
|
||||
use App\Services\Ploi\Ploi;
|
||||
use App\Traits\HasPloi;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
@@ -11,7 +11,7 @@ use Illuminate\Foundation\Bus\Dispatchable;
|
||||
|
||||
class DeleteSite implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels, HasPloi;
|
||||
|
||||
public $serverPloiId;
|
||||
public $sitePloiId;
|
||||
@@ -34,8 +34,6 @@ class DeleteSite implements ShouldQueue
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
$ploi = new Ploi(config('services.ploi.token'));
|
||||
|
||||
$ploi->server($this->serverPloiId)->sites()->delete($this->sitePloiId);
|
||||
$this->getPloi()->server($this->serverPloiId)->sites()->delete($this->sitePloiId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
namespace App\Jobs\Sites;
|
||||
|
||||
use App\Models\Site;
|
||||
use App\Services\Ploi\Ploi;
|
||||
use App\Traits\HasPloi;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use App\Traits\JobHasThresholds;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
@@ -13,7 +13,7 @@ use Illuminate\Foundation\Bus\Dispatchable;
|
||||
|
||||
class FetchSiteStatus implements ShouldQueue
|
||||
{
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels, JobHasThresholds;
|
||||
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels, JobHasThresholds, HasPloi;
|
||||
|
||||
public $site;
|
||||
|
||||
@@ -43,9 +43,7 @@ class FetchSiteStatus implements ShouldQueue
|
||||
return;
|
||||
}
|
||||
|
||||
$ploi = new Ploi;
|
||||
|
||||
$ploiSite = $ploi->server($this->site->server->ploi_id)->sites()->get($this->site->ploi_id)->getData();
|
||||
$ploiSite = $this->getPloi()->server($this->site->server->ploi_id)->sites()->get($this->site->ploi_id)->getData();
|
||||
|
||||
if ($ploiSite->status !== Site::STATUS_ACTIVE) {
|
||||
$this->incrementThreshold();
|
||||
|
||||
28
app/Models/Alert.php
Normal file
28
app/Models/Alert.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use DateTimeInterface;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Alert extends Model
|
||||
{
|
||||
const TYPE_INFO = 'info';
|
||||
const TYPE_WARNING = 'warning';
|
||||
const TYPE_DANGER = 'danger';
|
||||
|
||||
public $fillable = [
|
||||
'type',
|
||||
'message',
|
||||
'expires_at'
|
||||
];
|
||||
|
||||
public $dates = [
|
||||
'expires_at'
|
||||
];
|
||||
|
||||
protected function serializeDate(DateTimeInterface $date)
|
||||
{
|
||||
return $date->format('Y-m-d H:i:s');
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,8 @@ class Certificate extends Model
|
||||
|
||||
public $fillable = [
|
||||
'domain',
|
||||
'type'
|
||||
'type',
|
||||
'certificate',
|
||||
'private',
|
||||
];
|
||||
}
|
||||
|
||||
@@ -12,6 +12,9 @@ class Package extends Model
|
||||
const CURRENCY_NOK = 'nok';
|
||||
const CURRENCY_AUD = 'aud';
|
||||
const CURRENCY_CAD = 'cad';
|
||||
const CURRENCY_GBP = 'gbp';
|
||||
const CURRENCY_INR = 'inr';
|
||||
const CURRENCY_THB = 'thb';
|
||||
|
||||
public $fillable = [
|
||||
'name',
|
||||
@@ -19,6 +22,7 @@ class Package extends Model
|
||||
'currency',
|
||||
'price_hourly',
|
||||
'price_monthly',
|
||||
'price_yearly',
|
||||
'maximum_sites',
|
||||
'maximum_servers',
|
||||
'site_permissions',
|
||||
|
||||
@@ -8,6 +8,11 @@ class Provider extends Model
|
||||
{
|
||||
protected $guarded = [];
|
||||
|
||||
protected $casts = [
|
||||
'allowed_plans' => 'json',
|
||||
'allowed_regions' => 'json',
|
||||
];
|
||||
|
||||
public function getNameWithLabelAttribute()
|
||||
{
|
||||
$string = $this->name;
|
||||
@@ -41,12 +46,12 @@ class Provider extends Model
|
||||
|
||||
public static function booted()
|
||||
{
|
||||
static::deleting(function(self $provider){
|
||||
static::deleting(function (self $provider) {
|
||||
$provider->regions()->delete();
|
||||
$provider->plans()->delete();
|
||||
$provider->packages()->detach();
|
||||
|
||||
foreach($provider->servers as $server){
|
||||
foreach ($provider->servers as $server) {
|
||||
$server->provider_id = null;
|
||||
$server->provider_plan_id = null;
|
||||
$server->provider_region_id = null;
|
||||
|
||||
@@ -5,6 +5,9 @@ namespace App\Models;
|
||||
use DateTimeInterface;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
/**
|
||||
* @property mixed|string domain
|
||||
*/
|
||||
class Site extends Model
|
||||
{
|
||||
const STATUS_BUSY = 'busy';
|
||||
@@ -95,6 +98,10 @@ class Site extends Model
|
||||
|
||||
public static function booted()
|
||||
{
|
||||
static::creating(function (self $site) {
|
||||
$site->domain = strtolower($site->domain);
|
||||
});
|
||||
|
||||
static::created(function (self $site) {
|
||||
$site->systemUsers()->create();
|
||||
});
|
||||
|
||||
@@ -28,6 +28,7 @@ class User extends Authenticatable implements HasLocalePreference
|
||||
'address',
|
||||
'city',
|
||||
'country',
|
||||
'zip',
|
||||
'notes',
|
||||
'language',
|
||||
'blocked',
|
||||
@@ -109,6 +110,11 @@ class User extends Authenticatable implements HasLocalePreference
|
||||
return $this->hasMany(SupportTicket::class);
|
||||
}
|
||||
|
||||
public function supportTicketReplies()
|
||||
{
|
||||
return $this->hasMany(SupportTicketReply::class);
|
||||
}
|
||||
|
||||
public function systemLogs()
|
||||
{
|
||||
return $this->hasMany(SystemLog::class);
|
||||
@@ -138,6 +144,10 @@ class User extends Authenticatable implements HasLocalePreference
|
||||
$user->systemLogs()->delete();
|
||||
$user->servers()->detach();
|
||||
$user->sites()->detach();
|
||||
foreach ($user->supportTickets as $supportTicket) {
|
||||
$supportTicket->replies()->delete();
|
||||
}
|
||||
$user->supportTickets()->delete();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,16 +2,29 @@
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Casts\Encrypted;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class UserProvider extends Model
|
||||
{
|
||||
const TYPE_DNS = 'dns';
|
||||
const TYPE_CLOUDFLARE = 'cloudflare';
|
||||
|
||||
public $hidden = [
|
||||
'token'
|
||||
];
|
||||
|
||||
public $fillable = [
|
||||
'type',
|
||||
'token',
|
||||
'meta'
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'meta' => 'array',
|
||||
'token' => Encrypted::class,
|
||||
];
|
||||
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
|
||||
@@ -3,19 +3,10 @@
|
||||
namespace App\Providers;
|
||||
|
||||
use App\Models\Setting;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Pagination\UrlWindow;
|
||||
use Illuminate\Support\Facades\Request;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use Illuminate\Pagination\LengthAwarePaginator;
|
||||
|
||||
class AppServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* Register any application services.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register()
|
||||
{
|
||||
$this->app->singleton('settings', function ($app) {
|
||||
@@ -27,75 +18,5 @@ class AppServiceProvider extends ServiceProvider
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
if (!$this->app->request->is('api*')) {
|
||||
$this->registerLengthAwarePaginator();
|
||||
}
|
||||
}
|
||||
|
||||
protected function registerLengthAwarePaginator()
|
||||
{
|
||||
$this->app->bind(LengthAwarePaginator::class, function ($app, $values) {
|
||||
return new class(...array_values($values)) extends LengthAwarePaginator {
|
||||
public function only(...$attributes)
|
||||
{
|
||||
return $this->transform(function ($item) use ($attributes) {
|
||||
return $item->only($attributes);
|
||||
});
|
||||
}
|
||||
|
||||
public function transform($callback)
|
||||
{
|
||||
$this->items->transform($callback);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function toArray()
|
||||
{
|
||||
return [
|
||||
'data' => $this->items->toArray(),
|
||||
'links' => $this->links(),
|
||||
'per_page' => $this->perPage(),
|
||||
'total' => $this->total(),
|
||||
];
|
||||
}
|
||||
|
||||
public function links($view = null, $data = [])
|
||||
{
|
||||
$this->appends(Request::all());
|
||||
|
||||
$window = UrlWindow::make($this);
|
||||
|
||||
$elements = array_filter([
|
||||
$window['first'],
|
||||
is_array($window['slider']) ? '...' : null,
|
||||
$window['slider'],
|
||||
is_array($window['last']) ? '...' : null,
|
||||
$window['last'],
|
||||
]);
|
||||
|
||||
return Collection::make($elements)->flatMap(function ($item) {
|
||||
if (is_array($item)) {
|
||||
return Collection::make($item)->map(function ($url, $page) {
|
||||
return [
|
||||
'url' => $url,
|
||||
'label' => $page,
|
||||
'active' => $this->currentPage() === $page,
|
||||
];
|
||||
});
|
||||
} else {
|
||||
return [
|
||||
[
|
||||
'url' => null,
|
||||
'label' => '...',
|
||||
'active' => false,
|
||||
],
|
||||
];
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ class HorizonServiceProvider extends HorizonApplicationServiceProvider
|
||||
protected function gate()
|
||||
{
|
||||
Gate::define('viewHorizon', function ($user) {
|
||||
return $user->isAdmin();
|
||||
return $user->isAdmin() && !config('app.demo');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
58
app/Rules/CloudflareGeneralTest.php
Normal file
58
app/Rules/CloudflareGeneralTest.php
Normal file
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
namespace App\Rules;
|
||||
|
||||
use App\Services\Cloudflare;
|
||||
use Illuminate\Contracts\Validation\Rule;
|
||||
|
||||
class CloudflareGeneralTest implements Rule
|
||||
{
|
||||
public $cloudflareEmail;
|
||||
|
||||
/**
|
||||
* Create a new rule instance.
|
||||
*
|
||||
* @param $cloudflareEmail
|
||||
*/
|
||||
public function __construct($cloudflareEmail)
|
||||
{
|
||||
$this->cloudflareEmail = $cloudflareEmail;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the validation rule passes.
|
||||
*
|
||||
* @param string $attribute
|
||||
* @param mixed $value
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function passes($attribute, $value)
|
||||
{
|
||||
if (!$this->cloudflareEmail) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
$cloudflare = new Cloudflare($this->cloudflareEmail, $value);
|
||||
|
||||
if ($cloudflare->user()) {
|
||||
return true;
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation error message.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function message()
|
||||
{
|
||||
return __('We could not authenticate you with Cloudflare, are you sure this is the right API key? Also make sure your profile e-mail matches the one in Cloudflare.');
|
||||
}
|
||||
}
|
||||
140
app/Services/Cloudflare.php
Normal file
140
app/Services/Cloudflare.php
Normal file
@@ -0,0 +1,140 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services;
|
||||
|
||||
use Illuminate\Support\Str;
|
||||
use GuzzleHttp\Exception\ClientException;
|
||||
|
||||
class Cloudflare
|
||||
{
|
||||
public $adapter;
|
||||
public $zoneId;
|
||||
|
||||
public function __construct($email, $key)
|
||||
{
|
||||
$key = new \Cloudflare\API\Auth\APIKey($email, $key);
|
||||
$this->adapter = new \Cloudflare\API\Adapter\Guzzle($key);
|
||||
}
|
||||
|
||||
public function domains($match = '')
|
||||
{
|
||||
$zones = new \Cloudflare\API\Endpoints\Zones($this->adapter);
|
||||
|
||||
return collect(object_get($zones->listZones($match), 'result'));
|
||||
}
|
||||
|
||||
public function zone($zoneId)
|
||||
{
|
||||
$this->zoneId = $zoneId;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function listRecords($page = 1, $perPage = 50, $order = '', $direction = '', $type = '', $name = '', $content = '', $match = 'all')
|
||||
{
|
||||
$dns = new \Cloudflare\API\Endpoints\DNS($this->adapter);
|
||||
|
||||
if (!$dns || !$this->zoneId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return collect($dns->listRecords($this->zoneId, $type, $name, $content, $page, $perPage, $order, $direction, $match)->result)
|
||||
->map(function ($record) {
|
||||
// We add this property so our UI panel can see whether a record is being edited.
|
||||
$record->edit = false;
|
||||
|
||||
$record->display_content = Str::limit($record->content, 25);
|
||||
|
||||
return $record;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param null $content
|
||||
* @param string $type
|
||||
* @param int $ttl
|
||||
* @param bool $proxied
|
||||
* @param int $priority
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function addRecord($name, $content = null, $type = 'A', $ttl = 0, $proxied = true, $priority = '0')
|
||||
{
|
||||
if ($content == null && $type = 'A') {
|
||||
$content = $_SERVER['SERVER_ADDR'];
|
||||
}
|
||||
|
||||
$dns = new \Cloudflare\API\Endpoints\DNS($this->adapter);
|
||||
|
||||
try {
|
||||
return $dns->addRecord($this->zoneId, $type, $name, $content, $ttl, $proxied, $priority);
|
||||
} catch (ClientException $e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public function getRecordByValues($name, $type)
|
||||
{
|
||||
$dns = new \Cloudflare\API\Endpoints\DNS($this->adapter);
|
||||
|
||||
try {
|
||||
return $dns->getRecordID($this->zoneId, $type, $name);
|
||||
} catch (ClientException $e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public function deleteRecord($id)
|
||||
{
|
||||
$dns = new \Cloudflare\API\Endpoints\DNS($this->adapter);
|
||||
|
||||
try {
|
||||
return $dns->deleteRecord($this->zoneId, $id);
|
||||
} catch (ClientException $e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public function updateRecord($id, array $data = [])
|
||||
{
|
||||
$dns = new \Cloudflare\API\Endpoints\DNS($this->adapter);
|
||||
|
||||
try {
|
||||
$record = $dns->getRecordDetails($this->zoneId, $id);
|
||||
|
||||
return $dns->updateRecordDetails($this->zoneId, $id, [
|
||||
'type' => object_get($record, 'type'),
|
||||
'name' => array_get($data, 'name'),
|
||||
'content' => array_get($data, 'content'),
|
||||
]);
|
||||
} catch (ClientException $e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public function toggleProxy($id)
|
||||
{
|
||||
$dns = new \Cloudflare\API\Endpoints\DNS($this->adapter);
|
||||
|
||||
try {
|
||||
$record = $dns->getRecordDetails($this->zoneId, $id);
|
||||
|
||||
return $dns->updateRecordDetails($this->zoneId, $id, [
|
||||
'type' => object_get($record, 'type'),
|
||||
'name' => object_get($record, 'name'),
|
||||
'content' => object_get($record, 'content'),
|
||||
'proxied' => !object_get($record, 'proxied')
|
||||
]);
|
||||
} catch (ClientException $e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public function user()
|
||||
{
|
||||
$user = new \Cloudflare\API\Endpoints\User($this->adapter);
|
||||
|
||||
return $user->getUserDetails();
|
||||
}
|
||||
}
|
||||
@@ -21,4 +21,9 @@ class Unauthenticated extends Exception
|
||||
{
|
||||
parent::__construct($message);
|
||||
}
|
||||
|
||||
public function render($request)
|
||||
{
|
||||
return redirect()->route('dashboard')->with('error', 'Unable to authenticate with backend server, please check API keys and connection.');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ class Ploi
|
||||
|
||||
public function __construct(string $token = null, string $coreApiToken = null)
|
||||
{
|
||||
$this->url = app()->isLocal() ? 'http://core-api.ploi.test/' : 'https://core-api.ploi.io/';
|
||||
$this->url = config('services.ploi-api.url');
|
||||
|
||||
if (!$token) {
|
||||
$token = config('services.ploi.token');
|
||||
|
||||
@@ -43,7 +43,7 @@ class Certificate extends Resource
|
||||
return $this->getPloi()->makeAPICall($this->getEndpoint());
|
||||
}
|
||||
|
||||
public function create(string $certificate, string $type = 'letsencrypt'): stdClass
|
||||
public function create(string $certificate, string $type = 'letsencrypt', string $private = null): stdClass
|
||||
{
|
||||
// Remove the id
|
||||
$this->setId(null);
|
||||
@@ -51,8 +51,9 @@ class Certificate extends Resource
|
||||
// Set the options
|
||||
$options = [
|
||||
'body' => json_encode([
|
||||
'certificate' => $certificate,
|
||||
'type' => $type,
|
||||
'certificate' => $certificate,
|
||||
'private' => $private,
|
||||
]),
|
||||
];
|
||||
|
||||
|
||||
@@ -61,9 +61,9 @@ class Server extends Resource
|
||||
|
||||
public function create(
|
||||
string $name,
|
||||
int $provider,
|
||||
int $region,
|
||||
int $plan
|
||||
$provider,
|
||||
$region,
|
||||
$plan
|
||||
): stdClass {
|
||||
|
||||
// Remove the id
|
||||
@@ -89,8 +89,6 @@ class Server extends Resource
|
||||
} catch (NotValid $exception) {
|
||||
$errors = json_decode($exception->getMessage())->errors;
|
||||
|
||||
dd($errors);
|
||||
|
||||
throw $exception;
|
||||
}
|
||||
|
||||
|
||||
@@ -98,6 +98,13 @@ class Site extends Resource
|
||||
}
|
||||
|
||||
throw $exception;
|
||||
} catch (\Exception $exception) {
|
||||
info($exception->getMessage());
|
||||
}
|
||||
|
||||
// TODO: Debugging purposes
|
||||
if (!$response->getJson() || !isset($response->getJson()->data)) {
|
||||
throw new \Exception($response->getJson()->error ?? 'Unknown error has occured');
|
||||
}
|
||||
|
||||
// Set the id of the site
|
||||
@@ -142,7 +149,7 @@ class Site extends Resource
|
||||
return $response->getJson()->data;
|
||||
}
|
||||
|
||||
public function phpVersion($version = '7.4') :stdClass
|
||||
public function phpVersion($version = '7.4'): stdClass
|
||||
{
|
||||
// Set the options
|
||||
$options = [
|
||||
|
||||
@@ -19,4 +19,9 @@ class Synchronize extends Resource
|
||||
{
|
||||
return $this->getPloi()->makeAPICall($this->getEndpoint() . '/servers');
|
||||
}
|
||||
|
||||
public function sites()
|
||||
{
|
||||
return $this->getPloi()->makeAPICall($this->getEndpoint() . '/sites');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,4 +34,13 @@ class VersionChecker
|
||||
{
|
||||
return $this->currentVersion < $this->remoteVersion || $this->currentVersion != $this->remoteVersion;
|
||||
}
|
||||
|
||||
public function flushVersionData()
|
||||
{
|
||||
try {
|
||||
cache()->forget('ploi-core-current-version');
|
||||
cache()->forget('ploi-core-remote-version');
|
||||
} catch (\Exception $exception) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
13
app/Traits/HasPloi.php
Normal file
13
app/Traits/HasPloi.php
Normal file
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace App\Traits;
|
||||
|
||||
use App\Services\Ploi\Ploi;
|
||||
|
||||
trait HasPloi
|
||||
{
|
||||
protected function getPloi()
|
||||
{
|
||||
return new Ploi(config('services.ploi.token'));
|
||||
}
|
||||
}
|
||||
@@ -9,30 +9,32 @@
|
||||
],
|
||||
"license": "MIT",
|
||||
"require": {
|
||||
"php": "^7.3",
|
||||
"php": "^7.4|^8.0",
|
||||
"ext-json": "*",
|
||||
"cloudflare/sdk": "^1.1",
|
||||
"fideloper/proxy": "^4.2",
|
||||
"fruitcake/laravel-cors": "^1.0",
|
||||
"guzzlehttp/guzzle": "^6.2|^7.0.1",
|
||||
"inertiajs/inertia-laravel": "^0.3.1",
|
||||
"inertiajs/inertia-laravel": "^v0.4.3",
|
||||
"laravel/cashier": "^12.3",
|
||||
"laravel/framework": "^8.4",
|
||||
"laravel/horizon": "^5.0",
|
||||
"laravel/tinker": "^2.0",
|
||||
"laravel/ui": "^2.1",
|
||||
"laravel/ui": "^2.1|^3.3.0",
|
||||
"league/glide": "^1.6",
|
||||
"pragmarx/google2fa-laravel": "^1.3",
|
||||
"tightenco/ziggy": "^0.9.4"
|
||||
"predis/predis": "^1.1",
|
||||
"tightenco/ziggy": "^1.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"barryvdh/laravel-debugbar": "^3.3",
|
||||
"facade/ignition": "^2.3",
|
||||
"friendsofphp/php-cs-fixer": "^2.16",
|
||||
"fzaninotto/faker": "^1.9.1",
|
||||
"laravel/dusk": "^6.15",
|
||||
"mockery/mockery": "^1.3.1",
|
||||
"nunomaduro/collision": "^5.0",
|
||||
"phpunit/phpunit": "^8.5"
|
||||
"phpunit/phpunit": "^9.5.4"
|
||||
},
|
||||
"config": {
|
||||
"optimize-autoloader": true,
|
||||
|
||||
4203
composer.lock
generated
4203
composer.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -15,7 +15,7 @@ return [
|
||||
|
|
||||
*/
|
||||
|
||||
'domain' => null,
|
||||
'domain' => env('HORIZON_DOMAIN', null),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
@@ -28,7 +28,7 @@ return [
|
||||
|
|
||||
*/
|
||||
|
||||
'path' => 'horizon',
|
||||
'path' => env('HORIZON_PATH', 'horizon'),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
@@ -145,13 +145,13 @@ return [
|
||||
| Memory Limit (MB)
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This value describes the maximum amount of memory the Horizon worker
|
||||
| may consume before it is terminated and restarted. You should set
|
||||
| this value according to the resources available to your server.
|
||||
| This value describes the maximum amount of memory the Horizon master
|
||||
| supervisor may consume before it is terminated and restarted. For
|
||||
| configuring these limits on your workers, see the next section.
|
||||
|
|
||||
*/
|
||||
|
||||
'memory_limit' => 64,
|
||||
'memory_limit' => env('HORIZON_MEMORY_LIMIT', 64),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
@@ -164,6 +164,9 @@ return [
|
||||
|
|
||||
*/
|
||||
|
||||
'defaults' => [
|
||||
],
|
||||
|
||||
'environments' => [
|
||||
'production' => [
|
||||
'supervisor-1' => [
|
||||
|
||||
@@ -33,5 +33,9 @@ return [
|
||||
'ploi' => [
|
||||
'token' => env('PLOI_TOKEN'),
|
||||
'core-token' => env('PLOI_CORE_TOKEN')
|
||||
],
|
||||
|
||||
'ploi-api' => [
|
||||
'url' => env('PLOI_API_URL', 'https://core-api.ploi.io/')
|
||||
]
|
||||
];
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class CreateAlertsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('alerts', function (Blueprint $table) {
|
||||
$table->id();
|
||||
|
||||
$table->text('message')->nullable();
|
||||
$table->string('type')->nullable()->default(\App\Models\Alert::TYPE_INFO);
|
||||
|
||||
$table->timestamp('expires_at')->nullable();
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('alerts');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class AddMetaToUserProvidersTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('user_providers', function (Blueprint $table) {
|
||||
$table->json('meta')->nullable()->after('token');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('user_providers', function (Blueprint $table) {
|
||||
$table->dropColumn('meta');
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class AddZipToUsersTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('users', function (Blueprint $table) {
|
||||
$table->string('zip')->after('city')->nullable();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('users', function (Blueprint $table) {
|
||||
$table->dropColumn('zip');
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class AddPriceYearlyToPackagesTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('packages', function (Blueprint $table) {
|
||||
$table->decimal('price_yearly', 10, 4)->after('price_monthly')->default(0);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('packages', function (Blueprint $table) {
|
||||
$table->dropColumn('price_yearly');
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class AddColumnsToCertificatesTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('certificates', function (Blueprint $table) {
|
||||
$table->after('domain', function ($table) {
|
||||
$table->longText('certificate')->nullable();
|
||||
$table->longText('private')->nullable();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('certificates', function (Blueprint $table) {
|
||||
//
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class AddAllowedRegionsAndPlansToProvidersTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('providers', function (Blueprint $table) {
|
||||
$table->json('allowed_plans')->nullable()->after('name');
|
||||
$table->json('allowed_regions')->nullable()->after('allowed_plans');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('providers', function (Blueprint $table) {
|
||||
$table->dropColumn('allowed_plans', 'allowed_regions');
|
||||
});
|
||||
}
|
||||
}
|
||||
20186
package-lock.json
generated
20186
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
38
package.json
38
package.json
@@ -2,34 +2,40 @@
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "npm run development",
|
||||
"development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
|
||||
"watch": "npm run development -- --watch",
|
||||
"watch-poll": "npm run watch -- --watch-poll",
|
||||
"hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --disable-host-check --config=node_modules/laravel-mix/setup/webpack.config.js",
|
||||
"prod": "npm run production",
|
||||
"production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"
|
||||
"development": "mix",
|
||||
"watch": "mix watch",
|
||||
"watch-poll": "mix watch -- --watch-options-poll=1000",
|
||||
"hot": "mix watch --hot",
|
||||
"production": "mix --production"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
|
||||
"@inertiajs/inertia": "^0.4.3",
|
||||
"@inertiajs/inertia-vue": "^0.3.2",
|
||||
"@inertiajs/progress": "^0.1.2",
|
||||
"@tailwindcss/ui": "^0.3.0",
|
||||
"axios": "^0.19",
|
||||
"@inertiajs/inertia": "^0.10.0",
|
||||
"@inertiajs/inertia-vue": "^0.7.1",
|
||||
"@inertiajs/progress": "^0.2.6",
|
||||
"@tailwindcss/forms": "^0.3.2",
|
||||
"@tailwindcss/typography": "^0.4.1",
|
||||
"autoprefixer": "^10.2.5",
|
||||
"axios": "^0.21.1",
|
||||
"balloon-css": "^1.2.0",
|
||||
"cross-env": "^7.0",
|
||||
"laravel-mix": "^5.0.1",
|
||||
"cross-env": "^7.0.3",
|
||||
"laravel-mix": "^6.0.25",
|
||||
"lodash": "^4.17.15",
|
||||
"portal-vue": "^2.1.7",
|
||||
"postcss": "^8.2.13",
|
||||
"resolve-url-loader": "^3.1.0",
|
||||
"sass": "^1.15.2",
|
||||
"sass-loader": "^8.0.0",
|
||||
"tailwindcss": "^1.9.6",
|
||||
"v-click-outside": "^3.0.1",
|
||||
"tailwindcss": "^2.2.4",
|
||||
"v-click-outside": "^3.1.2",
|
||||
"vue": "^2.6.11",
|
||||
"vue-clipboard2": "^0.3.1",
|
||||
"vue-loader": "^15.9.6",
|
||||
"vue-meta": "^2.4.0",
|
||||
"vue-template-compiler": "^2.6.11",
|
||||
"vuex": "^3.5.1"
|
||||
"vuex": "^3.6.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"vue-simplemde": "^2.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
6
public/css/app.css
vendored
6
public/css/app.css
vendored
File diff suppressed because one or more lines are too long
1
public/js/0.js
vendored
1
public/js/0.js
vendored
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user