Compare commits
2 commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
8b29ab65ef | ||
![]() |
03dcdc5a4d |
9 changed files with 669 additions and 442 deletions
|
@ -5,5 +5,9 @@ php:
|
|||
finder:
|
||||
not-name:
|
||||
- index.php
|
||||
js: true
|
||||
- server.php
|
||||
js:
|
||||
finder:
|
||||
not-name:
|
||||
- webpack.mix.js
|
||||
css: true
|
||||
|
|
|
@ -65,7 +65,7 @@ To correctly manage remote servers Spikster has to be on a public IP address (IP
|
|||
|
||||
## Spikster LEMP environment
|
||||
- nginx: 1.18
|
||||
- PHP-FPM: 8.3, 8.2, 8.1, 8.0, 7.4
|
||||
- PHP-FPM: 8.2, 8.1, 8.0, 7.4
|
||||
- MySql: 8
|
||||
- node: 16
|
||||
- npm: 8
|
||||
|
@ -73,11 +73,11 @@ To correctly manage remote servers Spikster has to be on a public IP address (IP
|
|||
|
||||
## Screenshots
|
||||
|
||||

|
||||
<img src="https://spikster.com/images/docs/server.png">
|
||||
|
||||

|
||||
<img src="https://spikster.com/images/docs/site.png">
|
||||
|
||||

|
||||
<img src="https://spikster.com/images/docs/cron.png">
|
||||
|
||||
## Why use Spikster?
|
||||
Spikster is easy, stable, powerful and free for any personal and commercial use and it's a perfect alternative to Cpanel, Plesk, Runcloud, CyberPanel, DirectAdmin, Forge and similar software...
|
||||
|
|
83
app/Livewire/Server/Packages/Overview.php
Normal file
83
app/Livewire/Server/Packages/Overview.php
Normal file
|
@ -0,0 +1,83 @@
|
|||
<?php
|
||||
|
||||
namespace App\Livewire\Server\Packages;
|
||||
|
||||
use App\Models\Server;
|
||||
use Livewire\Component;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
|
||||
class Overview extends Component
|
||||
{
|
||||
|
||||
public $server;
|
||||
public $server_id;
|
||||
public $items;
|
||||
|
||||
public function mount($server_id)
|
||||
{
|
||||
$this->server_id = $server_id;
|
||||
$this->server = Server::where('server_id', $server_id)->first();
|
||||
$this->items = $this->getPackages();
|
||||
$this->items['installed'] = $this->getInstalledPackages();
|
||||
|
||||
}
|
||||
|
||||
public function render()
|
||||
{
|
||||
return view('livewire.server.packages.overview');
|
||||
}
|
||||
|
||||
private function getPackages()
|
||||
{
|
||||
return [
|
||||
'services' => [
|
||||
['name' => 'spamassassin', 'description' => 'SpamAssassin is a mail filter which attempts to identify spam using a variety of mechanisms including text analysis, Bayesian filtering, DNS blocklists, and collaborative filtering databases.'],
|
||||
['name' => 'nginx', 'description' => 'Nginx is a web server which can also be used as a reverse proxy, load balancer, mail proxy and HTTP cache.'],
|
||||
['name' => 'exim4', 'description' => 'Exim is a message transfer agent (MTA) developed at the University of Cambridge for use on Unix systems connected to the Internet.'],
|
||||
['name' => 'dovecot', 'description' => 'Dovecot is an open-source IMAP and POP3 server for Unix-like operating systems, written primarily with security in mind.'],
|
||||
['name' => 'php8.3-fpm', 'description' => 'PHP-FPM (FastCGI Process Manager) is an alternative PHP FastCGI implementation with some additional features useful for sites of any size, especially busier sites.'],
|
||||
['name' => 'clamav-daemon', 'description' => 'ClamAV is an open-source antivirus engine for detecting trojans, viruses, malware & other malicious threats.'],
|
||||
['name' => 'redis-server', 'description' => 'Redis is an open-source, in-memory data structure store, used as a database, cache, and message broker.'],
|
||||
['name' => 'mysql', 'description' => 'MySQL is an open-source relational database management system.'],
|
||||
],
|
||||
'processes' => [
|
||||
['name' => 'glances', 'description' => 'Glances is a cross-platform monitoring tool which aims to present a large amount of monitoring information through a curses or Web-based interface.'],
|
||||
],
|
||||
'packages' => [
|
||||
['name' => 'roundcube', 'description' => 'Roundcube is a browser-based multilingual IMAP client with an application-like user interface.'],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
public function getInstalledPackages()
|
||||
{
|
||||
$response = Http::withHeaders([
|
||||
'Authorization' => 'Bearer ' . session('token'),
|
||||
])->get($this->server->ip. '/servers/' . $this->server_id . '/packages');
|
||||
|
||||
return $response->json();
|
||||
|
||||
}
|
||||
|
||||
public function getInstalledPackagesMock()
|
||||
{
|
||||
return [
|
||||
'services' => [
|
||||
['name' => 'spamassassin', 'status' => 'ACTIVE'],
|
||||
['name' => 'nginx', 'status' => 'ACTIVE'],
|
||||
['name' => 'exim4', 'status' => 'ACTIVE'],
|
||||
['name' => 'dovecot', 'status' => 'ACTIVE'],
|
||||
['name' => 'php8.3-fpm', 'status' => 'ACTIVE'],
|
||||
['name' => 'clamav-daemon', 'status' => 'INACTIVE'],
|
||||
['name' => 'redis-server', 'status' => 'ACTIVE'],
|
||||
['name' => 'mysql', 'status' => 'ACTIVE'],
|
||||
],
|
||||
'processes' => [
|
||||
['name' => 'glances', 'status' => 'ACTIVE'],
|
||||
],
|
||||
'packages' => [
|
||||
['name' => 'roundcube', 'status' => 'INSTALLED'],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
|
@ -2,9 +2,9 @@
|
|||
|
||||
namespace App\Livewire\Server;
|
||||
|
||||
use Livewire\Component;
|
||||
use App\Models\Server;
|
||||
use Http;
|
||||
use Livewire\Component;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
|
||||
class PackagesInstalled extends Component
|
||||
{
|
||||
|
@ -29,7 +29,7 @@ class PackagesInstalled extends Component
|
|||
|
||||
public function getInstalledPackages()
|
||||
{
|
||||
$url = $this->server->ip . '/api/servers/' . $this->server->server_id . '/packages';
|
||||
$url = $this->server->ip . '/api/servers/' . $this->server->server_id . '/services';
|
||||
$response = Http::get($url);
|
||||
$response = $response->json()[0];
|
||||
foreach ($response as $key => $value) {
|
||||
|
|
32
phpunit.xml
32
phpunit.xml
|
@ -1,33 +1,31 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
|
||||
xsi:noNamespaceSchemaLocation="./vendor/phpunit/phpunit/phpunit.xsd"
|
||||
bootstrap="vendor/autoload.php"
|
||||
colors="true"
|
||||
>
|
||||
<testsuites>
|
||||
<testsuite name="Unit">
|
||||
<directory>tests/Unit</directory>
|
||||
<directory suffix="Test.php">./tests/Unit</directory>
|
||||
</testsuite>
|
||||
<testsuite name="Feature">
|
||||
<directory>tests/Feature</directory>
|
||||
<directory suffix="Test.php">./tests/Feature</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
<source>
|
||||
<coverage processUncoveredFiles="true">
|
||||
<include>
|
||||
<directory>app</directory>
|
||||
<directory suffix=".php">./app</directory>
|
||||
</include>
|
||||
</source>
|
||||
</coverage>
|
||||
<php>
|
||||
<env name="APP_ENV" value="testing"/>
|
||||
<env name="APP_MAINTENANCE_DRIVER" value="file"/>
|
||||
<env name="BCRYPT_ROUNDS" value="4"/>
|
||||
<env name="CACHE_STORE" value="array"/>
|
||||
<!-- <env name="DB_CONNECTION" value="sqlite"/> -->
|
||||
<!-- <env name="DB_DATABASE" value=":memory:"/> -->
|
||||
<env name="MAIL_MAILER" value="array"/>
|
||||
<env name="PULSE_ENABLED" value="false"/>
|
||||
<env name="QUEUE_CONNECTION" value="sync"/>
|
||||
<env name="SESSION_DRIVER" value="array"/>
|
||||
<env name="TELESCOPE_ENABLED" value="false"/>
|
||||
<server name="APP_ENV" value="testing"/>
|
||||
<server name="BCRYPT_ROUNDS" value="4"/>
|
||||
<server name="CACHE_DRIVER" value="array"/>
|
||||
<!-- <server name="DB_CONNECTION" value="sqlite"/> -->
|
||||
<!-- <server name="DB_DATABASE" value=":memory:"/> -->
|
||||
<server name="MAIL_MAILER" value="array"/>
|
||||
<server name="QUEUE_CONNECTION" value="sync"/>
|
||||
<server name="SESSION_DRIVER" value="array"/>
|
||||
<server name="TELESCOPE_ENABLED" value="false"/>
|
||||
</php>
|
||||
</phpunit>
|
||||
|
|
27
resources/views/livewire/manage-service.blade.php
Normal file
27
resources/views/livewire/manage-service.blade.php
Normal file
|
@ -0,0 +1,27 @@
|
|||
<div>
|
||||
@if($message)
|
||||
<div class="alert alert-info">{{ $message }}</div>
|
||||
@endif
|
||||
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Service</th>
|
||||
<th>Status</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach($services as $service)
|
||||
<tr>
|
||||
<td>{{ $service['name'] }}</td>
|
||||
<td>{{ $service['status'] }}</td>
|
||||
<td>
|
||||
<button wire:click="restartService('{{ $service['name'] }}')"
|
||||
class="btn btn-primary">Restart</button>
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
47
resources/views/livewire/server/packages/overview.blade.php
Normal file
47
resources/views/livewire/server/packages/overview.blade.php
Normal file
|
@ -0,0 +1,47 @@
|
|||
<div class="grid grid-cols-1 gap-4 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4">
|
||||
|
||||
@for ($i = 0; $i < count($items['installed'] ?? []); $i++)
|
||||
@php
|
||||
$packages = $items[array_keys($items)[$i]];
|
||||
$installed = $items['installed'][array_keys($items['installed'])[$i]];
|
||||
@endphp
|
||||
@for ($x = 0; $x < count($packages ?? []); $x++)
|
||||
<x-card header="{{ ucfirst($packages[$x]['name']) }}" size="md" dark="false">
|
||||
<div class="flex flex-col my-4 gap-y-4">
|
||||
<div class="flex my-4 gap-x-4">
|
||||
@if (array_keys($items['installed'])[$i] == 'packages')
|
||||
@if ($installed[$x]['status'] == 'INSTALLED')
|
||||
<div class="flex-col">
|
||||
<p class="pb-4 text-green-500">Installed</p>
|
||||
<x-button variant="danger" size="sm">Uninstall</x-button>
|
||||
</div>
|
||||
@else
|
||||
<x-button variant="primary" size="sm">Install</x-button>
|
||||
@endif
|
||||
@else
|
||||
@if ($installed[$x]['status'] == 'ACTIVE')
|
||||
<div class="flex-col">
|
||||
<span class="pb-4 text-green-500">Active</span>
|
||||
<div class="flex mt-4 gap-x-4">
|
||||
<x-button variant="danger" size="sm">Stop</x-button>
|
||||
<x-button variant="warning" size="sm">Restart</x-button>
|
||||
</div>
|
||||
</div>
|
||||
@elseif ($installed[$x]['status'] == 'INACTIVE')
|
||||
<div class="flex-col gap-4">
|
||||
<span class="pb-4 text-yellow-500">Inactive</span>
|
||||
<div class="flex-1 mt-4 gap-x-4">
|
||||
<x-button variant="success" size="sm">Start</x-button>
|
||||
</div>
|
||||
</div>
|
||||
@else
|
||||
<x-button variant="primary" size="sm">Install</x-button>
|
||||
<x-button variant="danger" size="sm">Uninstall</x-button>
|
||||
@endif
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</x-card>
|
||||
@endfor
|
||||
@endfor
|
||||
</div>
|
|
@ -8,56 +8,83 @@
|
|||
|
||||
|
||||
@section('content')
|
||||
<div x-data="{ tab: 'monitor' }">
|
||||
<ol class="breadcrumbs">
|
||||
<li class="breadcrumb-item active">IP:<b><span class="ml-1" id="serveriptop"></span></b></li>
|
||||
<li class="breadcrumb-item active">{{ __('spikster.sites') }}:<b><span class="ml-1" id="serversites"></span></b></li>
|
||||
<li class="breadcrumb-item active">Ping:<b><span class="ml-1" id="serverping"><i class="fas fa-circle-notch fa-spin"></i></span></b></li>
|
||||
</ol>
|
||||
<div x-data="{ tab: 'monitor' }">
|
||||
<ol class="breadcrumbs">
|
||||
<li class="breadcrumb-item active">IP:<b><span class="ml-1" id="serveriptop"></span></b></li>
|
||||
<li class="breadcrumb-item active">{{ __('spikster.sites') }}:<b><span class="ml-1" id="serversites"></span></b>
|
||||
</li>
|
||||
<li class="breadcrumb-item active">Ping:<b><span class="ml-1" id="serverping"><i
|
||||
class="fas fa-circle-notch fa-spin"></i></span></b></li>
|
||||
</ol>
|
||||
|
||||
<div class="pb-4">
|
||||
<div class="sm:hidden">
|
||||
<label for="tabs" class="sr-only">Select a tab</label>
|
||||
<!-- Use an "onChange" listener to redirect the user to the selected tab URL. -->
|
||||
<select id="tabs" name="tabs" class="block w-full rounded-md border-gray-300 focus:border-indigo-500 focus:ring-indigo-500">
|
||||
<option selected>Monitor</option>
|
||||
<option>Server information</option>
|
||||
<option>Security</option>
|
||||
<option>Tools</option>
|
||||
</select>
|
||||
<div class="pb-4">
|
||||
<div class="sm:hidden">
|
||||
<label for="tabs" class="sr-only">Select a tab</label>
|
||||
<!-- Use an "onChange" listener to redirect the user to the selected tab URL. -->
|
||||
<select id="tabs" name="tabs"
|
||||
class="block w-full border-gray-300 rounded-md focus:border-indigo-500 focus:ring-indigo-500"
|
||||
@change="tab = $event.target.value">
|
||||
<option value="monitor" :selected="tab === 'monitor'">
|
||||
Monitor
|
||||
</option>
|
||||
<option value="server" :selected="tab === 'server'">
|
||||
Server information
|
||||
</option>
|
||||
<option value="packages" :selected="tab === 'packages'">
|
||||
Packages
|
||||
</option>
|
||||
<option value="security" :selected="tab === 'security'">
|
||||
Security
|
||||
</option>
|
||||
<option value="tools" :selected="tab === 'tools'">
|
||||
Tools
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="hidden sm:block">
|
||||
<nav class="flex space-x-4" aria-label="Tabs">
|
||||
<!-- Current: "bg-gray-200 text-gray-800", Default: "text-gray-600 hover:text-gray-800" -->
|
||||
<a @click="tab = 'monitor'" clas="tab" :class="tab === 'monitor' ? 'tab-item-active' : 'tab-item'"
|
||||
aria-current="page">Monitor</a>
|
||||
<a @click="tab = 'server'" :class="tab === 'server' ? 'tab-item-active' : 'tab-item'">Server
|
||||
information</a>
|
||||
<a @click="tab = 'packages'" :class="tab === 'packages' ? 'tab-item-active' : 'tab-item'">Packages</a>
|
||||
<a @click="tab = 'security'" :class="tab === 'security' ? 'tab-item-active' : 'tab-item'">Security</a>
|
||||
<a @click="tab = 'tools'" :class="tab === 'tools' ? 'tab-item-active' : 'tab-item'">Tools</a>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
<div class="hidden sm:block">
|
||||
<nav class="flex space-x-4" aria-label="Tabs">
|
||||
<!-- Current: "bg-gray-200 text-gray-800", Default: "text-gray-600 hover:text-gray-800" -->
|
||||
<a @click="tab = 'monitor'" clas="tab" :class="tab === 'monitor' ? 'tab-item-active' : 'tab-item'" aria-current="page">Monitor</a>
|
||||
<a @click="tab = 'server'" :class="tab === 'server' ? 'tab-item-active' : 'tab-item'">Server information</a>
|
||||
<a @click="tab = 'security'" :class="tab === 'security' ? 'tab-item-active' : 'tab-item'">Security</a>
|
||||
<a @click="tab = 'tools'" :class="tab === 'tools' ? 'tab-item-active' : 'tab-item'">Tools</a>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="grid grid-cols-2 gap-4" x-show="tab === 'monitor'">
|
||||
<div class="grid grid-cols-2 gap-4" x-show="tab === 'monitor'">
|
||||
@livewire('stats.cpu', ['server_id' => $server_id])
|
||||
@livewire('stats.mem', ['server_id' => $server_id])
|
||||
@livewire('stats.load', ['server_id' => $server_id])
|
||||
@livewire('stats.disk', ['server_id' => $server_id])
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="" x-show="tab === 'packages'">
|
||||
@livewire('server.packages.overview', ['server_id' => $server_id])
|
||||
</div>
|
||||
|
||||
|
||||
<div class="grid grid-cols-1 sm:grid-cols-2 xl:grid-cols-3 gap-4" x-show="tab === 'server'">
|
||||
<x-card header="{{ __('spikster.server_information') }}" size="md" dark="false">
|
||||
{{-- <canvas id="cpuChart" width="100%" height="40"></canvas> --}}
|
||||
<x-input type="text" label="{{ __('spikster.server_name') }}:" placeholder="e.g. Production" id="servername" autocomplete="off" />
|
||||
<x-input type="text" label="{{ __('spikster.server_ip') }}:" placeholder="e.g. 123.123.123.123" id="serverip" autocomplete="off" />
|
||||
<x-input type="text" label="{{ __('spikster.server_provider') }}:" placeholder="e.g. Digital Ocean" id="serverprovider" autocomplete="off" />
|
||||
<x-input type="text" label="{{ __('spikster.server_location') }}:" placeholder="e.g. Amsterdam" id="serverlocation" autocomplete="off" />
|
||||
<x-button type="button" id="updateServer">{{ __('spikster.update') }}</x-button>
|
||||
</x-card>
|
||||
<x-card header="{{ __('spikster.system_services') }}" size="md" dark="false">
|
||||
<div class="grid grid-cols-1 xl:grid-cols-2 gap-4">
|
||||
|
||||
<div class="grid grid-cols-1 gap-4 sm:grid-cols-2 xl:grid-cols-3" x-show="tab === 'server'">
|
||||
<x-card header="{{ __('spikster.server_information') }}" size="md" dark="false">
|
||||
{{-- <canvas id="cpuChart" width="100%" height="40"></canvas> --}}
|
||||
<x-input type="text" label="{{ __('spikster.server_name') }}:" placeholder="e.g. Production"
|
||||
id="servername" autocomplete="off" />
|
||||
<x-input type="text" label="{{ __('spikster.server_ip') }}:" placeholder="e.g. 123.123.123.123"
|
||||
id="serverip" autocomplete="off" />
|
||||
<x-input type="text" label="{{ __('spikster.server_provider') }}:" placeholder="e.g. Digital Ocean"
|
||||
id="serverprovider" autocomplete="off" />
|
||||
<x-input type="text" label="{{ __('spikster.server_location') }}:" placeholder="e.g. Amsterdam"
|
||||
id="serverlocation" autocomplete="off" />
|
||||
<x-button type="button" id="updateServer">{{ __('spikster.update') }}</x-button>
|
||||
</x-card>
|
||||
<x-card header="{{ __('spikster.system_services') }}" size="md" dark="false">
|
||||
{{-- <div class="grid grid-cols-1 gap-4 xl:grid-cols-2">
|
||||
<div class="flex justify-between gap-4">
|
||||
<p>nginx</p>
|
||||
<x-button type="button" variant="warning" id="restartnginx">{{ __('spikster.restart') }} </x-button>
|
||||
|
@ -77,437 +104,457 @@
|
|||
<div class="flex justify-between gap-4">
|
||||
<p>Supervisor</p>
|
||||
<x-button type="button" variant="warning" id="restartsupervisor">{{ __('spikster.restart') }} </x-button>
|
||||
</div>
|
||||
</div>
|
||||
</x-card>
|
||||
<x-card header="Logs" size="md" dark="false">
|
||||
<a href="{{route('logs', $server_id)}}">
|
||||
<x-button>
|
||||
Open Logs
|
||||
</x-button>
|
||||
</a>
|
||||
</x-card>
|
||||
</div>
|
||||
<div class="flex gap-x-4" x-show="tab === 'security'">
|
||||
<div class="w-1/2">
|
||||
<x-card header="Security" size="md" dark="false">
|
||||
<p>Fail2ban</p>
|
||||
<div>
|
||||
<a href="{{route('server.fail2ban', $server_id)}}" class="btn btn-primary" type="button" id="">Open Fail2ban</a>
|
||||
</div>
|
||||
</div> --}}
|
||||
{{-- </div> --}}
|
||||
<livewire-manage-service :server_id="$server_id" />
|
||||
</x-card>
|
||||
<x-card header="Logs" size="md" dark="false">
|
||||
<a href="{{ route('logs', $server_id) }}">
|
||||
<x-button>
|
||||
Open Logs
|
||||
</x-button>
|
||||
</a>
|
||||
</x-card>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex gap-x-4" x-show="tab === 'tools'">
|
||||
<div class="w-1/3">
|
||||
<x-card header="{{ __('spikster.tools') }}" size="md" dark="false">
|
||||
<p>{{ __('spikster.php_cli_version') }}:</p>
|
||||
<div class="input-group">
|
||||
<select class="form-control" id="phpver">
|
||||
<option value="8.3" id="php83">8.3</option>
|
||||
<option value="8.2" id="php82">8.2</option>
|
||||
<option value="8.1" id="php81">8.1</option>
|
||||
<option value="8.0" id="php80">8.0</option>
|
||||
<option value="7.4" id="php74">7.4</option>
|
||||
</select>
|
||||
<div class="input-group-append">
|
||||
<button class="btn btn-primary" type="button" id="changephp"><i class="fas fa-edit"></i></button>
|
||||
<div class="flex gap-x-4" x-show="tab === 'security'">
|
||||
<div class="w-1/2">
|
||||
<x-card header="Security" size="md" dark="false">
|
||||
<p>Fail2ban</p>
|
||||
<div>
|
||||
<a href="{{ route('server.fail2ban', $server_id) }}" class="btn btn-primary" type="button"
|
||||
id="">Open Fail2ban</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-4">
|
||||
<p class="mb-2">{{ __('spikster.manage_cron_jobs') }}:</p>
|
||||
<button class="btn btn-primary" type="button" id="editcrontab">{{ __('spikster.edit_crontab') }}</button>
|
||||
</div>
|
||||
<div class="mt-4">
|
||||
<p class="mb-2">{{ __('spikster.reset_cipi_password') }}:</p>
|
||||
<button class="btn btn-danger" type="button" id="rootreset">{{ __('spikster.require_reset_cipi_password') }}</button>
|
||||
|
||||
</div>
|
||||
<div class="mt-4">
|
||||
{{-- <p class="mb-2">{{ __('spikster.cipi_build_version') }}:</p>
|
||||
<span class="btn btn-secondary" id="serverbuild"></span> --}}
|
||||
</div>
|
||||
<div class="space"></div>
|
||||
</x-card>
|
||||
</x-card>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex gap-x-4" x-show="tab === 'tools'">
|
||||
<div class="w-1/3">
|
||||
<x-card header="{{ __('spikster.tools') }}" size="md" dark="false">
|
||||
<p>{{ __('spikster.php_cli_version') }}:</p>
|
||||
<div class="input-group">
|
||||
<select class="form-control" id="phpver">
|
||||
<option value="8.3" id="php83">8.3</option>
|
||||
<option value="8.2" id="php82">8.2</option>
|
||||
<option value="8.1" id="php81">8.1</option>
|
||||
<option value="8.0" id="php80">8.0</option>
|
||||
<option value="7.4" id="php74">7.4</option>
|
||||
</select>
|
||||
<div class="input-group-append">
|
||||
<button class="btn btn-primary" type="button" id="changephp"><i
|
||||
class="fas fa-edit"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-4">
|
||||
<p class="mb-2">{{ __('spikster.manage_cron_jobs') }}:</p>
|
||||
<button class="btn btn-primary" type="button"
|
||||
id="editcrontab">{{ __('spikster.edit_crontab') }}</button>
|
||||
</div>
|
||||
<div class="mt-4">
|
||||
<p class="mb-2">{{ __('spikster.reset_cipi_password') }}:</p>
|
||||
<button class="btn btn-danger" type="button"
|
||||
id="rootreset">{{ __('spikster.require_reset_cipi_password') }}</button>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-4">
|
||||
{{-- <p class="mb-2">{{ __('spikster.cipi_build_version') }}:</p>
|
||||
<span class="btn btn-secondary" id="serverbuild"></span> --}}
|
||||
</div>
|
||||
<div class="space"></div>
|
||||
</x-card>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
@endsection
|
||||
|
||||
|
||||
|
||||
@section('extra')
|
||||
<input type="hidden" id="currentip">
|
||||
<dialog class="modal fade" id="updateServerModal" tabindex="-1" role="dialog" aria-labelledby="updateServerModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog" role="document" id="updateserverdialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="updateServerModalLabel">{{ __('spikster.update_server_modal_title') }}</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p>{{ __('spikster.update_server_modal_text') }}</p>
|
||||
<p class="d-none" id="ipnotice"><b>{!! __('spikster.update_server_modal_ip') !!}</b></p>
|
||||
<div class="text-center">
|
||||
<button class="btn btn-primary" type="button" id="submit">{{ __('spikster.confirm') }} </button>
|
||||
<input type="hidden" id="currentip">
|
||||
<dialog class="modal fade" id="updateServerModal" tabindex="-1" role="dialog"
|
||||
aria-labelledby="updateServerModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog" role="document" id="updateserverdialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="updateServerModalLabel">
|
||||
{{ __('spikster.update_server_modal_title') }}</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p>{{ __('spikster.update_server_modal_text') }}</p>
|
||||
<p class="d-none" id="ipnotice"><b>{!! __('spikster.update_server_modal_ip') !!}</b></p>
|
||||
<div class="text-center">
|
||||
<button class="btn btn-primary" type="button" id="submit">{{ __('spikster.confirm') }}
|
||||
</button>
|
||||
</div>
|
||||
<div class="space"></div>
|
||||
</div>
|
||||
<div class="space"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</dialog>
|
||||
<dialog class="modal fade" id="crontabModal" tabindex="-1" role="dialog" aria-labelledby="crontabModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="crontabModalLabel">{{ __('spikster.server_crontab') }}</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p>{{ __('spikster.server_crontab_edit') }}:</p>
|
||||
<div id="crontab" style="height:250px;width:100%;"></div>
|
||||
<div class="space"></div>
|
||||
<div class="text-center">
|
||||
<button class="btn btn-primary" type="button" id="crontabsubmit">{{ __('spikster.save') }} <i class="fas fa-circle-notch fa-spin d-none" id="crontableloading"></i></button>
|
||||
</dialog>
|
||||
<dialog class="modal fade" id="crontabModal" tabindex="-1" role="dialog" aria-labelledby="crontabModalLabel"
|
||||
aria-hidden="true">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="crontabModalLabel">{{ __('spikster.server_crontab') }}</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p>{{ __('spikster.server_crontab_edit') }}:</p>
|
||||
<div id="crontab" style="height:250px;width:100%;"></div>
|
||||
<div class="space"></div>
|
||||
<div class="text-center">
|
||||
<button class="btn btn-primary" type="button" id="crontabsubmit">{{ __('spikster.save') }}
|
||||
<i class="fas fa-circle-notch fa-spin d-none" id="crontableloading"></i></button>
|
||||
</div>
|
||||
<div class="space"></div>
|
||||
</div>
|
||||
<div class="space"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</dialog>
|
||||
<dialog class="modal fade" id="rootresetModal" tabindex="-1" role="dialog" aria-labelledby="rootresetModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="rootresetModalLabel">{{ __('spikster.require_password_reset_modal_title') }}</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p>{{ __('spikster.require_password_reset_modal_text') }}</p>
|
||||
<div class="space"></div>
|
||||
<div class="text-center">
|
||||
<button class="btn btn-danger" type="button" id="rootresetsubmit">{{ __('spikster.confirm') }} <i class="fas fa-circle-notch fa-spin d-none" id="rootresetloading"></i></button>
|
||||
</dialog>
|
||||
<dialog class="modal fade" id="rootresetModal" tabindex="-1" role="dialog"
|
||||
aria-labelledby="rootresetModalLabel" aria-hidden="true">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title" id="rootresetModalLabel">
|
||||
{{ __('spikster.require_password_reset_modal_title') }}</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p>{{ __('spikster.require_password_reset_modal_text') }}</p>
|
||||
<div class="space"></div>
|
||||
<div class="text-center">
|
||||
<button class="btn btn-danger" type="button"
|
||||
id="rootresetsubmit">{{ __('spikster.confirm') }} <i
|
||||
class="fas fa-circle-notch fa-spin d-none" id="rootresetloading"></i></button>
|
||||
</div>
|
||||
<div class="space"></div>
|
||||
</div>
|
||||
<div class="space"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</dialog>
|
||||
</div>
|
||||
</dialog>
|
||||
</div>
|
||||
@endsection
|
||||
|
||||
|
||||
|
||||
@section('css')
|
||||
|
||||
@endsection
|
||||
|
||||
|
||||
|
||||
@section('js')
|
||||
<script>
|
||||
// Get Server info
|
||||
$('#mainloading').removeClass('d-none');
|
||||
<script>
|
||||
// Get Server info
|
||||
$('#mainloading').removeClass('d-none');
|
||||
|
||||
// Crontab editor
|
||||
var crontab = ace.edit("crontab");
|
||||
crontab.setTheme("ace/theme/monokai");
|
||||
crontab.session.setMode("ace/mode/sh");
|
||||
// Crontab editor
|
||||
var crontab = ace.edit("crontab");
|
||||
crontab.setTheme("ace/theme/monokai");
|
||||
crontab.session.setMode("ace/mode/sh");
|
||||
|
||||
// Crontab edit
|
||||
$('#editcrontab').click(function() {
|
||||
$('#crontabModal').modal();
|
||||
});
|
||||
|
||||
// Crontab Submit
|
||||
$('#crontabsubmit').click(function() {
|
||||
$.ajax({
|
||||
url: '/api/servers/{{ $server_id }}',
|
||||
type: 'PATCH',
|
||||
contentType: 'application/json',
|
||||
dataType: 'json',
|
||||
data: JSON.stringify({
|
||||
'cron': crontab.getSession().getValue(),
|
||||
}),
|
||||
beforeSend: function() {
|
||||
$('#crontableloading').removeClass('d-none');
|
||||
},
|
||||
success: function(data) {
|
||||
$('#crontableloading').addClass('d-none');
|
||||
$('#crontabModal').modal('toggle');
|
||||
serverInit();
|
||||
},
|
||||
// Crontab edit
|
||||
$('#editcrontab').click(function() {
|
||||
$('#crontabModal').modal();
|
||||
});
|
||||
});
|
||||
|
||||
// Server Init
|
||||
function serverInit() {
|
||||
getDataNoDT('/api/servers',false);
|
||||
$.ajax({
|
||||
url: '/api/servers/{{ $server_id }}',
|
||||
type: 'GET',
|
||||
success: function(data) {
|
||||
$('#mainloading').addClass('d-none');
|
||||
$('#serveriptop').html(data.ip);
|
||||
$('#serversites').html(data.sites);
|
||||
$('#maintitle').html('- '+data.name);
|
||||
$('#servername').val(data.name);
|
||||
$('#serverip').val(data.ip);
|
||||
$('#serverprovider').val(data.provider);
|
||||
$('#serverlocation').val(data.location);
|
||||
$('#currentip').val(data.ip);
|
||||
crontab.session.setValue(data.cron);
|
||||
$('#serverbuild').empty();
|
||||
if(data.build) {
|
||||
$('#serverbuild').html(data.build);
|
||||
} else {
|
||||
$('#serverbuild').html('{{ __('spikster.unknown') }}');
|
||||
}
|
||||
switch (data.php) {
|
||||
case '8.3':
|
||||
$('#php83').attr("selected","selected");
|
||||
break;
|
||||
case '8.2':
|
||||
$('#php82').attr("selected","selected");
|
||||
break;
|
||||
case '8.1':
|
||||
$('#php81').attr("selected","selected");
|
||||
break;
|
||||
case '8.0':
|
||||
$('#php80').attr("selected","selected");
|
||||
break;
|
||||
case '7.4':
|
||||
$('#php74').attr("selected","selected");
|
||||
break;
|
||||
case '7.3':
|
||||
// Append legacy php 7.3
|
||||
$('#phpver').append('<option value="7.3" selected>7.3</option>');
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
},
|
||||
// Crontab Submit
|
||||
$('#crontabsubmit').click(function() {
|
||||
$.ajax({
|
||||
url: '/api/servers/{{ $server_id }}',
|
||||
type: 'PATCH',
|
||||
contentType: 'application/json',
|
||||
dataType: 'json',
|
||||
data: JSON.stringify({
|
||||
'cron': crontab.getSession().getValue(),
|
||||
}),
|
||||
beforeSend: function() {
|
||||
$('#crontableloading').removeClass('d-none');
|
||||
},
|
||||
success: function(data) {
|
||||
$('#crontableloading').addClass('d-none');
|
||||
$('#crontabModal').modal('toggle');
|
||||
serverInit();
|
||||
},
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Init variables
|
||||
serverInit();
|
||||
// Server Init
|
||||
function serverInit() {
|
||||
getDataNoDT('/api/servers', false);
|
||||
$.ajax({
|
||||
url: '/api/servers/{{ $server_id }}',
|
||||
type: 'GET',
|
||||
success: function(data) {
|
||||
$('#mainloading').addClass('d-none');
|
||||
$('#serveriptop').html(data.ip);
|
||||
$('#serversites').html(data.sites);
|
||||
$('#maintitle').html('- ' + data.name);
|
||||
$('#servername').val(data.name);
|
||||
$('#serverip').val(data.ip);
|
||||
$('#serverprovider').val(data.provider);
|
||||
$('#serverlocation').val(data.location);
|
||||
$('#currentip').val(data.ip);
|
||||
crontab.session.setValue(data.cron);
|
||||
$('#serverbuild').empty();
|
||||
if (data.build) {
|
||||
$('#serverbuild').html(data.build);
|
||||
} else {
|
||||
$('#serverbuild').html('{{ __('spikster.unknown') }}');
|
||||
}
|
||||
switch (data.php) {
|
||||
case '8.3':
|
||||
$('#php83').attr("selected", "selected");
|
||||
break;
|
||||
case '8.2':
|
||||
$('#php82').attr("selected", "selected");
|
||||
break;
|
||||
case '8.1':
|
||||
$('#php81').attr("selected", "selected");
|
||||
break;
|
||||
case '8.0':
|
||||
$('#php80').attr("selected", "selected");
|
||||
break;
|
||||
case '7.4':
|
||||
$('#php74').attr("selected", "selected");
|
||||
break;
|
||||
case '7.3':
|
||||
// Append legacy php 7.3
|
||||
$('#phpver').append('<option value="7.3" selected>7.3</option>');
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
// Ping
|
||||
function getPing() {
|
||||
$.ajax({
|
||||
url: '/api/servers/{{ $server_id }}/ping',
|
||||
type: 'GET',
|
||||
beforeSend: function() {
|
||||
$('#serverping').empty();
|
||||
$('#serverping').html('<i class="fas fa-circle-notch fa-spin" title="{{ __('spikster.loading_data') }}"></i>');
|
||||
},
|
||||
success: function(data) {
|
||||
$('#serverping').empty();
|
||||
$('#serverping').html('<i class="fas fa-check text-success"></i>');
|
||||
},
|
||||
});
|
||||
}
|
||||
setInterval(function() {
|
||||
getPing();
|
||||
}, 10000);
|
||||
getPing();
|
||||
|
||||
// Change PHP
|
||||
$('#changephp').click(function() {
|
||||
$.ajax({
|
||||
url: '/api/servers/{{ $server_id }}',
|
||||
type: 'PATCH',
|
||||
contentType: 'application/json',
|
||||
dataType: 'json',
|
||||
data: JSON.stringify({
|
||||
'php': $('#phpver').val(),
|
||||
}),
|
||||
beforeSend: function() {
|
||||
$('#changephp').html('<i class="fas fa-circle-notch fa-spin" title="{{ __('spikster.loading_please_wait') }}"></i>');
|
||||
},
|
||||
success: function(data) {
|
||||
$('#changephp').empty();
|
||||
$('#changephp').html('<i class="fas fas fa-edit"></i>');
|
||||
},
|
||||
});
|
||||
// Init variables
|
||||
serverInit();
|
||||
});
|
||||
|
||||
// Restart nginx
|
||||
$('#restartnginx').click(function() {
|
||||
$.ajax({
|
||||
url: '/api/servers/{{ $server_id }}/servicerestart/nginx',
|
||||
type: 'POST',
|
||||
beforeSend: function() {
|
||||
$('#loadingnginx').removeClass('d-none');
|
||||
},
|
||||
success: function(data) {
|
||||
$('#loadingnginx').addClass('d-none');
|
||||
},
|
||||
// Ping
|
||||
function getPing() {
|
||||
$.ajax({
|
||||
url: '/api/servers/{{ $server_id }}/ping',
|
||||
type: 'GET',
|
||||
beforeSend: function() {
|
||||
$('#serverping').empty();
|
||||
$('#serverping').html(
|
||||
'<i class="fas fa-circle-notch fa-spin" title="{{ __('spikster.loading_data') }}"></i>'
|
||||
);
|
||||
},
|
||||
success: function(data) {
|
||||
$('#serverping').empty();
|
||||
$('#serverping').html('<i class="fas fa-check text-success"></i>');
|
||||
},
|
||||
});
|
||||
}
|
||||
setInterval(function() {
|
||||
getPing();
|
||||
}, 10000);
|
||||
getPing();
|
||||
|
||||
// Change PHP
|
||||
$('#changephp').click(function() {
|
||||
$.ajax({
|
||||
url: '/api/servers/{{ $server_id }}',
|
||||
type: 'PATCH',
|
||||
contentType: 'application/json',
|
||||
dataType: 'json',
|
||||
data: JSON.stringify({
|
||||
'php': $('#phpver').val(),
|
||||
}),
|
||||
beforeSend: function() {
|
||||
$('#changephp').html(
|
||||
'<i class="fas fa-circle-notch fa-spin" title="{{ __('spikster.loading_please_wait') }}"></i>'
|
||||
);
|
||||
},
|
||||
success: function(data) {
|
||||
$('#changephp').empty();
|
||||
$('#changephp').html('<i class="fas fa-edit"></i>');
|
||||
},
|
||||
});
|
||||
serverInit();
|
||||
});
|
||||
});
|
||||
|
||||
// Restart php
|
||||
$('#restartphp').click(function() {
|
||||
$.ajax({
|
||||
url: '/api/servers/{{ $server_id }}/servicerestart/php',
|
||||
type: 'POST',
|
||||
beforeSend: function() {
|
||||
$('#loadingphp').removeClass('d-none');
|
||||
},
|
||||
success: function(data) {
|
||||
$('#loadingphp').addClass('d-none');
|
||||
},
|
||||
// Restart nginx
|
||||
$('#restartnginx').click(function() {
|
||||
$.ajax({
|
||||
url: '/api/servers/{{ $server_id }}/servicerestart/nginx',
|
||||
type: 'POST',
|
||||
beforeSend: function() {
|
||||
$('#loadingnginx').removeClass('d-none');
|
||||
},
|
||||
success: function(data) {
|
||||
$('#loadingnginx').addClass('d-none');
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Restart mysql
|
||||
$('#restartmysql').click(function() {
|
||||
$.ajax({
|
||||
url: '/api/servers/{{ $server_id }}/servicerestart/mysql',
|
||||
type: 'POST',
|
||||
beforeSend: function() {
|
||||
$('#loadingmysql').removeClass('d-none');
|
||||
},
|
||||
success: function(data) {
|
||||
$('#loadingmysql').addClass('d-none');
|
||||
},
|
||||
// Restart php
|
||||
$('#restartphp').click(function() {
|
||||
$.ajax({
|
||||
url: '/api/servers/{{ $server_id }}/servicerestart/php',
|
||||
type: 'POST',
|
||||
beforeSend: function() {
|
||||
$('#loadingphp').removeClass('d-none');
|
||||
},
|
||||
success: function(data) {
|
||||
$('#loadingphp').addClass('d-none');
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Restart redis
|
||||
$('#restartredis').click(function() {
|
||||
$.ajax({
|
||||
url: '/api/servers/{{ $server_id }}/servicerestart/redis',
|
||||
type: 'POST',
|
||||
beforeSend: function() {
|
||||
$('#loadingredis').removeClass('d-none');
|
||||
},
|
||||
success: function(data) {
|
||||
$('#loadingredis').addClass('d-none');
|
||||
},
|
||||
// Restart mysql
|
||||
$('#restartmysql').click(function() {
|
||||
$.ajax({
|
||||
url: '/api/servers/{{ $server_id }}/servicerestart/mysql',
|
||||
type: 'POST',
|
||||
beforeSend: function() {
|
||||
$('#loadingmysql').removeClass('d-none');
|
||||
},
|
||||
success: function(data) {
|
||||
$('#loadingmysql').addClass('d-none');
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Restart supervisor
|
||||
$('#restartsupervisor').click(function() {
|
||||
$.ajax({
|
||||
url: '/api/servers/{{ $server_id }}/servicerestart/supervisor',
|
||||
type: 'POST',
|
||||
beforeSend: function() {
|
||||
$('#loadingsupervisor').removeClass('d-none');
|
||||
},
|
||||
success: function(data) {
|
||||
$('#loadingsupervisor').addClass('d-none');
|
||||
},
|
||||
// Restart redis
|
||||
$('#restartredis').click(function() {
|
||||
$.ajax({
|
||||
url: '/api/servers/{{ $server_id }}/servicerestart/redis',
|
||||
type: 'POST',
|
||||
beforeSend: function() {
|
||||
$('#loadingredis').removeClass('d-none');
|
||||
},
|
||||
success: function(data) {
|
||||
$('#loadingredis').addClass('d-none');
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Root Reset
|
||||
$('#rootreset').click(function() {
|
||||
$('#rootresetModal').modal();
|
||||
});
|
||||
// Restart supervisor
|
||||
$('#restartsupervisor').click(function() {
|
||||
$.ajax({
|
||||
url: '/api/servers/{{ $server_id }}/servicerestart/supervisor',
|
||||
type: 'POST',
|
||||
beforeSend: function() {
|
||||
$('#loadingsupervisor').removeClass('d-none');
|
||||
},
|
||||
success: function(data) {
|
||||
$('#loadingsupervisor').addClass('d-none');
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
// Root Reset Submit
|
||||
$('#rootresetsubmit').click(function() {
|
||||
$('#rootresetloading').removeClass('d-none');
|
||||
$.ajax({
|
||||
url: '/api/servers/{{ $server_id }}/rootreset',
|
||||
type: 'POST',
|
||||
success: function(data) {
|
||||
success('{{ __('spikster.new_password_success') }}:<br><b>'+data.password+'</b>');
|
||||
$(window).scrollTop(0);
|
||||
$('#rootresetModal').modal('toggle');
|
||||
},
|
||||
complete: function() {
|
||||
$('#rootresetloading').addClass('d-none');
|
||||
// Root Reset
|
||||
$('#rootreset').click(function() {
|
||||
$('#rootresetModal').modal();
|
||||
});
|
||||
|
||||
// Root Reset Submit
|
||||
$('#rootresetsubmit').click(function() {
|
||||
$('#rootresetloading').removeClass('d-none');
|
||||
$.ajax({
|
||||
url: '/api/servers/{{ $server_id }}/rootreset',
|
||||
type: 'POST',
|
||||
success: function(data) {
|
||||
success('{{ __('spikster.new_password_success') }}:<br><b>' + data.password +
|
||||
'</b>');
|
||||
$(window).scrollTop(0);
|
||||
$('#rootresetModal').modal('toggle');
|
||||
},
|
||||
complete: function() {
|
||||
$('#rootresetloading').addClass('d-none');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
//Check IP conflict (edit)
|
||||
function ipConflictEdit(ip, server_id) {
|
||||
conflict = 0;
|
||||
JSON.parse(localStorage.otherdata).forEach(server => {
|
||||
if (ip === server.ip && server.server_id !== server_id) {
|
||||
conflict = conflict + 1;
|
||||
}
|
||||
});
|
||||
return conflict;
|
||||
}
|
||||
|
||||
// Update Server
|
||||
$('#updateServer').click(function() {
|
||||
$('#ipnotice').addClass('d-none');
|
||||
if ($('#serverip').val() != $('#currentip').val()) {
|
||||
$('#newip').html($('#serverip').val());
|
||||
$('#ipnotice').removeClass('d-none');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
//Check IP conflict (edit)
|
||||
function ipConflictEdit(ip,server_id) {
|
||||
conflict = 0;
|
||||
JSON.parse(localStorage.otherdata).forEach(server => {
|
||||
if(ip === server.ip && server.server_id !== server_id) {
|
||||
conflict = conflict + 1;
|
||||
validation = true;
|
||||
if (!$('#servername').val() || $('#servername').val().length < 3) {
|
||||
$('#servername').addClass('is-invalid');
|
||||
$('#submit').addClass('disabled');
|
||||
validation = false;
|
||||
}
|
||||
});
|
||||
return conflict;
|
||||
}
|
||||
|
||||
// Update Server
|
||||
$('#updateServer').click(function() {
|
||||
$('#ipnotice').addClass('d-none');
|
||||
if($('#serverip').val() != $('#currentip').val()) {
|
||||
$('#newip').html($('#serverip').val());
|
||||
$('#ipnotice').removeClass('d-none');
|
||||
}
|
||||
validation = true;
|
||||
if(!$('#servername').val() || $('#servername').val().length < 3) {
|
||||
$('#servername').addClass('is-invalid');
|
||||
$('#submit').addClass('disabled');
|
||||
validation = false;
|
||||
}
|
||||
server_id = '{{ $server_id }}';
|
||||
if(!$('#serverip').val() || !ipValidate($('#serverip').val()) || ipConflictEdit($('#serverip').val(),server_id) > 0) {
|
||||
$('#serverip').addClass('is-invalid');
|
||||
$('#submit').addClass('disabled');
|
||||
validation = false;
|
||||
}
|
||||
if(validation) {
|
||||
$('#loading').addClass('d-none');
|
||||
$('#updateServerModal').modal();
|
||||
}
|
||||
});
|
||||
|
||||
// Update Server Validation
|
||||
$('#servername').keyup(function() {
|
||||
$('#servername').removeClass('is-invalid');
|
||||
$('#submit').removeClass('disabled');
|
||||
});
|
||||
$('#serverip').keyup(function() {
|
||||
$('#serverip').removeClass('is-invalid');
|
||||
$('#submit').removeClass('disabled');
|
||||
});
|
||||
|
||||
// Update Server Submit
|
||||
$('#submit').click(function() {
|
||||
$.ajax({
|
||||
url: '/api/servers/{{ $server_id }}',
|
||||
type: 'PATCH',
|
||||
contentType: 'application/json',
|
||||
dataType: 'json',
|
||||
data: JSON.stringify({
|
||||
'name': $('#servername').val(),
|
||||
'ip': $('#serverip').val(),
|
||||
'provider': $('#serverprovider').val(),
|
||||
'location': $('#serverlocation').val()
|
||||
}),
|
||||
beforeSend: function() {
|
||||
$('#loading').removeClass('d-none');
|
||||
},
|
||||
success: function(data) {
|
||||
serverInit();
|
||||
server_id = '{{ $server_id }}';
|
||||
if (!$('#serverip').val() || !ipValidate($('#serverip').val()) || ipConflictEdit($('#serverip').val(),
|
||||
server_id) > 0) {
|
||||
$('#serverip').addClass('is-invalid');
|
||||
$('#submit').addClass('disabled');
|
||||
validation = false;
|
||||
}
|
||||
if (validation) {
|
||||
$('#loading').addClass('d-none');
|
||||
},
|
||||
complete: function() {
|
||||
$('#ipnotice').addClass('d-none');
|
||||
$('#updateServerModal').modal('toggle');
|
||||
$('#updateServerModal').modal();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Charts style
|
||||
Chart.defaults.global.defaultFontFamily = '-apple-system,system-ui,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif';
|
||||
Chart.defaults.global.defaultFontColor = '#292b2c';
|
||||
</script>
|
||||
// Update Server Validation
|
||||
$('#servername').keyup(function() {
|
||||
$('#servername').removeClass('is-invalid');
|
||||
$('#submit').removeClass('disabled');
|
||||
});
|
||||
$('#serverip').keyup(function() {
|
||||
$('#serverip').removeClass('is-invalid');
|
||||
$('#submit').removeClass('disabled');
|
||||
});
|
||||
|
||||
// Update Server Submit
|
||||
$('#submit').click(function() {
|
||||
$.ajax({
|
||||
url: '/api/servers/{{ $server_id }}',
|
||||
type: 'PATCH',
|
||||
contentType: 'application/json',
|
||||
dataType: 'json',
|
||||
data: JSON.stringify({
|
||||
'name': $('#servername').val(),
|
||||
'ip': $('#serverip').val(),
|
||||
'provider': $('#serverprovider').val(),
|
||||
'location': $('#serverlocation').val()
|
||||
}),
|
||||
beforeSend: function() {
|
||||
$('#loading').removeClass('d-none');
|
||||
},
|
||||
success: function(data) {
|
||||
serverInit();
|
||||
$('#loading').addClass('d-none');
|
||||
},
|
||||
complete: function() {
|
||||
$('#ipnotice').addClass('d-none');
|
||||
$('#updateServerModal').modal('toggle');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Charts style
|
||||
Chart.defaults.global.defaultFontFamily =
|
||||
'-apple-system,system-ui,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif';
|
||||
Chart.defaults.global.defaultFontColor = '#292b2c';
|
||||
</script>
|
||||
@endsection
|
||||
|
|
21
server.php
Normal file
21
server.php
Normal file
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Laravel - A PHP Framework For Web Artisans
|
||||
*
|
||||
* @package Laravel
|
||||
* @author Taylor Otwell <taylor@laravel.com>
|
||||
*/
|
||||
|
||||
$uri = urldecode(
|
||||
parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH)
|
||||
);
|
||||
|
||||
// This file allows us to emulate Apache's "mod_rewrite" functionality from the
|
||||
// built-in PHP web server. This provides a convenient way to test a Laravel
|
||||
// application without having installed a "real" web server software here.
|
||||
if ($uri !== '/' && file_exists(__DIR__.'/public'.$uri)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
require_once __DIR__.'/public/index.php';
|
Loading…
Add table
Reference in a new issue