feat: Implement DNS management with dedicated models, repositories, requests, controllers, and services, while refactoring authentication by removing Passport and Sanctum.
This commit is contained in:
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace App\Facades;
|
||||
|
||||
use Illuminate\Support\Facades\Facade;
|
||||
|
||||
/**
|
||||
* @method static string url(string $ip)
|
||||
*/
|
||||
class BaseHelperFacade extends Facade
|
||||
{
|
||||
protected static function getFacadeAccessor(): string
|
||||
{
|
||||
return 'base-helper';
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a base HTTPS URL from an IP address or hostname.
|
||||
*/
|
||||
public static function url(string $ip): string
|
||||
{
|
||||
$ip = rtrim($ip, '/');
|
||||
|
||||
if (!str_starts_with($ip, 'http://') && !str_starts_with($ip, 'https://')) {
|
||||
return 'https://' . $ip;
|
||||
}
|
||||
|
||||
return $ip;
|
||||
}
|
||||
}
|
||||
@@ -19,7 +19,7 @@ class AuthController extends Controller
|
||||
'password' => 'required|string',
|
||||
]);
|
||||
|
||||
$token = Auth::guard('admins-api')->attempt($request->only('username', 'password'));
|
||||
$token = Auth::guard('admin')->attempt($request->only('username', 'password'));
|
||||
|
||||
if (!$token) {
|
||||
return response()->json([
|
||||
@@ -28,7 +28,7 @@ class AuthController extends Controller
|
||||
], 401);
|
||||
}
|
||||
|
||||
$user = Auth::guard('admins-api')->user();
|
||||
$user = Auth::guard('admin')->user();
|
||||
|
||||
return response()->json([
|
||||
'error' => false,
|
||||
@@ -43,7 +43,7 @@ class AuthController extends Controller
|
||||
|
||||
public function me(): JsonResponse
|
||||
{
|
||||
$user = Auth::guard('admins-api')->user();
|
||||
$user = Auth::guard('admin')->user();
|
||||
|
||||
return response()->json([
|
||||
'error' => false,
|
||||
@@ -76,7 +76,7 @@ class AuthController extends Controller
|
||||
|
||||
public function logout(): JsonResponse
|
||||
{
|
||||
Auth::guard('admins-api')->logout();
|
||||
Auth::guard('admin')->logout();
|
||||
|
||||
return response()->json([
|
||||
'error' => false,
|
||||
|
||||
@@ -165,7 +165,7 @@ class OrderController extends Controller
|
||||
'discount_id' => $request->discount_id ?? 0,
|
||||
'amount' => $total + ($total * (10 / 100)),
|
||||
'payment_id' => $request->payment_id,
|
||||
'user_id' => Auth::guard('admins-api')->id(),
|
||||
'user_id' => Auth::guard('admin')->id(),
|
||||
'status' => $request->status,
|
||||
'client_ip' => $request->getClientIp()
|
||||
];
|
||||
|
||||
@@ -0,0 +1,377 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Backend;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Domain\DomainRemoveRequest;
|
||||
use App\Http\Requests\Domain\DomainRequest;
|
||||
use App\Repositories\DnsManager\Domain\DnsDomainRepositoryInterface;
|
||||
use App\Services\ServerService;
|
||||
use Exception;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\Cache;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class DomainController extends Controller
|
||||
{
|
||||
public function __construct(
|
||||
public DnsDomainRepositoryInterface $domainRepository,
|
||||
public ServerService $serverService
|
||||
) {}
|
||||
|
||||
public function index()
|
||||
{
|
||||
$title = 'Domains';
|
||||
return view('Backend.domains.index', compact('title'));
|
||||
}
|
||||
|
||||
public function getAll()
|
||||
{
|
||||
$domains = $this->domainRepository->filter([], ['users', 'server'])->map(function ($domain) {
|
||||
return [
|
||||
'id' => $domain->id,
|
||||
'name' => $domain->domain_name,
|
||||
'server' => $domain->server ? $domain->server->ip_address : '',
|
||||
'user' => $domain->users->pluck('name')->implode(', '),
|
||||
'checkbox' => '<input class="form-check-input m-0 align-middle" value="' . $domain->id . '" type="checkbox" aria-label="Select tag">',
|
||||
'created_at' => Carbon::parse($domain->created_at)->format('Y-m-d H:i:s'),
|
||||
'action' => $this->domainActionButtons($domain),
|
||||
];
|
||||
});
|
||||
|
||||
return response()->json(['data' => $domains]);
|
||||
}
|
||||
|
||||
public function create()
|
||||
{
|
||||
$title = 'Add Domain';
|
||||
return view('Backend.domains.create', compact('title'));
|
||||
}
|
||||
|
||||
public function store(DomainRequest $request)
|
||||
{
|
||||
$validated = $request->validated();
|
||||
|
||||
$isCreated = $this->domainRepository->findDomain($validated['domain_name']);
|
||||
if (!empty($isCreated)) {
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => "Domain '{$validated['domain_name']}' đã tồn tại trong hệ thống!",
|
||||
]);
|
||||
}
|
||||
|
||||
DB::beginTransaction();
|
||||
try {
|
||||
$userIds = $validated['user_id'] ?? [];
|
||||
$domainData = collect($validated)->except('user_id')->toArray();
|
||||
|
||||
$domain = $this->domainRepository->create($domainData);
|
||||
$domain->users()->attach($userIds);
|
||||
$domain->save();
|
||||
|
||||
try {
|
||||
$server = $this->serverService->findServerByID($domain->dns_manager_server_id);
|
||||
|
||||
if (!$server) {
|
||||
throw new Exception("Không tìm thấy server với ID: {$domain->dns_manager_server_id}");
|
||||
}
|
||||
|
||||
$existingDomainInfo = $this->serverService->getDomainInfo($domain->domain_name);
|
||||
|
||||
if ($existingDomainInfo) {
|
||||
$this->domainRepository->update($domain->id, [
|
||||
'is_created' => 1,
|
||||
'plesk_id' => $existingDomainInfo['id'],
|
||||
]);
|
||||
} else {
|
||||
$response = $this->serverService->createDomain($domain->toArray());
|
||||
|
||||
if (!$response || !isset($response['id'])) {
|
||||
throw new Exception('Không thể tạo domain trên server. Vui lòng kiểm tra lại thông tin server.');
|
||||
}
|
||||
|
||||
$this->domainRepository->update($domain->id, [
|
||||
'is_created' => 1,
|
||||
'plesk_id' => $response['id'],
|
||||
]);
|
||||
}
|
||||
} catch (Exception $domainError) {
|
||||
Log::error('Lỗi khi tạo domain: ' . $domainError->getMessage());
|
||||
}
|
||||
|
||||
DB::commit();
|
||||
|
||||
$domain = $domain->refresh();
|
||||
$message = $domain->is_created == 1 && $domain->plesk_id
|
||||
? "Domain '{$domain->domain_name}' đã được xử lý thành công trên server!"
|
||||
: "Domain '{$domain->domain_name}' đã được lưu vào database nhưng chưa thể xử lý trên server.";
|
||||
|
||||
return response()->json(['success' => true, 'message' => $message, 'url' => route('admin.domain.index')]);
|
||||
} catch (Exception $error) {
|
||||
DB::rollBack();
|
||||
return response()->json(['success' => false, 'message' => 'Có lỗi xảy ra: ' . $error->getMessage()]);
|
||||
}
|
||||
}
|
||||
|
||||
public function edit(int $id)
|
||||
{
|
||||
$domain = $this->domainRepository->find($id);
|
||||
if (empty($domain)) {
|
||||
return back()->withErrors("Không tìm thấy domain với ID: {$id}");
|
||||
}
|
||||
|
||||
$title = 'Edit domain';
|
||||
return view('Backend.domains.edit', compact('title', 'domain'));
|
||||
}
|
||||
|
||||
public function update(DomainRequest $request, int $id)
|
||||
{
|
||||
$domain = $this->domainRepository->find($id);
|
||||
|
||||
if (empty($domain)) {
|
||||
return response()->json(['success' => false, 'message' => "Không tìm thấy domain với ID: {$id}"]);
|
||||
}
|
||||
|
||||
$validated = $request->validated();
|
||||
|
||||
DB::beginTransaction();
|
||||
try {
|
||||
$userIds = $validated['user_id'] ?? [];
|
||||
$domainData = collect($validated)->except('user_id')->toArray();
|
||||
|
||||
$this->domainRepository->update($id, $domainData);
|
||||
$domain->users()->sync($userIds);
|
||||
|
||||
try {
|
||||
$updatedDomain = $this->domainRepository->find($id);
|
||||
$server = $this->serverService->findServerByID($updatedDomain->dns_manager_server_id);
|
||||
|
||||
if (!$server) {
|
||||
throw new Exception("Không tìm thấy server với ID: {$updatedDomain->dns_manager_server_id}");
|
||||
}
|
||||
|
||||
$existingDomainInfo = $this->serverService->getDomainInfo($updatedDomain->domain_name);
|
||||
|
||||
if ($existingDomainInfo) {
|
||||
$this->serverService->updateDomain($existingDomainInfo['id'], $updatedDomain->toArray());
|
||||
$this->domainRepository->update($updatedDomain->id, [
|
||||
'is_created' => 1,
|
||||
'plesk_id' => $existingDomainInfo['id'],
|
||||
]);
|
||||
} else {
|
||||
$response = $this->serverService->createDomain($updatedDomain->toArray());
|
||||
|
||||
if (!$response || !isset($response['id'])) {
|
||||
throw new Exception('Không thể tạo domain trên server.');
|
||||
}
|
||||
|
||||
$this->domainRepository->update($updatedDomain->id, [
|
||||
'is_created' => 1,
|
||||
'plesk_id' => $response['id'],
|
||||
]);
|
||||
}
|
||||
} catch (Exception $domainError) {
|
||||
Log::error('Lỗi khi cập nhật domain: ' . $domainError->getMessage());
|
||||
}
|
||||
|
||||
DB::commit();
|
||||
|
||||
$updatedDomain = $this->domainRepository->find($id);
|
||||
$message = $updatedDomain->is_created == 1 && $updatedDomain->plesk_id
|
||||
? "Domain '{$updatedDomain->domain_name}' đã được cập nhật thành công trên server!"
|
||||
: "Domain '{$updatedDomain->domain_name}' đã được cập nhật trong database nhưng chưa thể xử lý trên server.";
|
||||
|
||||
return response()->json(['success' => true, 'message' => $message, 'url' => route('admin.domain.index')]);
|
||||
} catch (Exception $error) {
|
||||
DB::rollBack();
|
||||
return response()->json(['success' => false, 'message' => 'Có lỗi xảy ra: ' . $error->getMessage()]);
|
||||
}
|
||||
}
|
||||
|
||||
public function record(int $id = 0)
|
||||
{
|
||||
$domain = $this->domainRepository->findWithRelations($id, ['record']);
|
||||
|
||||
if (empty($domain)) {
|
||||
return back()->withErrors("Không tìm thấy domain với ID: {$id}");
|
||||
}
|
||||
|
||||
$title = strtoupper($domain->domain_name) . ' Records';
|
||||
return view('Backend.domains.view', compact('domain', 'title', 'id'));
|
||||
}
|
||||
|
||||
public function destroy(int $id)
|
||||
{
|
||||
$domain = $this->domainRepository->find($id);
|
||||
if (!$domain) {
|
||||
return response()->json(['success' => false, 'message' => "Không tìm thấy domain với ID: {$id}"]);
|
||||
}
|
||||
|
||||
try {
|
||||
if ($domain->is_created !== 1 || !$domain->plesk_id) {
|
||||
$this->domainRepository->delete($domain->id);
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => "Domain '{$domain->domain_name}' đã được xóa khỏi database.",
|
||||
'url' => route('admin.domain.index'),
|
||||
]);
|
||||
}
|
||||
|
||||
$server = $this->serverService->findServerByID($domain->dns_manager_server_id);
|
||||
|
||||
if (!$server) {
|
||||
return response()->json(['success' => false, 'message' => "Không tìm thấy server với ID: {$domain->dns_manager_server_id}"]);
|
||||
}
|
||||
|
||||
$removed = $this->serverService->removeDomain($domain->plesk_id);
|
||||
|
||||
if (!$removed) {
|
||||
return response()->json(['success' => false, 'message' => "Không thể xóa domain '{$domain->domain_name}' trên server."]);
|
||||
}
|
||||
|
||||
$this->domainRepository->delete($domain->id);
|
||||
$this->clearDomainCaches($domain);
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => "Domain '{$domain->domain_name}' đã được xóa thành công khỏi server và database!",
|
||||
'url' => route('admin.domain.index'),
|
||||
]);
|
||||
} catch (Exception $error) {
|
||||
return response()->json(['success' => false, 'message' => 'Có lỗi xảy ra khi xóa domain: ' . $error->getMessage()]);
|
||||
}
|
||||
}
|
||||
|
||||
public function destroyCustom(DomainRemoveRequest $request)
|
||||
{
|
||||
$request->validated();
|
||||
|
||||
$domains = $this->domainRepository->findWhereIn('id', $request->get('ids'));
|
||||
|
||||
if (!$domains || $domains->isEmpty()) {
|
||||
return response()->json(['success' => false, 'message' => 'Không tìm thấy domain nào.']);
|
||||
}
|
||||
|
||||
$successCount = 0;
|
||||
$errorCount = 0;
|
||||
$errors = [];
|
||||
|
||||
foreach ($domains as $domain) {
|
||||
try {
|
||||
if ($domain->is_created !== 1 || !$domain->plesk_id) {
|
||||
$this->domainRepository->delete($domain->id);
|
||||
$successCount++;
|
||||
continue;
|
||||
}
|
||||
|
||||
$server = $this->serverService->findServerByID($domain->dns_manager_server_id);
|
||||
|
||||
if (!$server) {
|
||||
$errors[] = "Domain '{$domain->domain_name}': Không tìm thấy server";
|
||||
$errorCount++;
|
||||
continue;
|
||||
}
|
||||
|
||||
$removed = $this->serverService->removeDomain($domain->plesk_id);
|
||||
|
||||
if (!$removed) {
|
||||
$errors[] = "Domain '{$domain->domain_name}': Không thể xóa trên server";
|
||||
$errorCount++;
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->domainRepository->delete($domain->id);
|
||||
$this->clearDomainCaches($domain);
|
||||
$successCount++;
|
||||
} catch (Exception $error) {
|
||||
$errors[] = "Domain '{$domain->domain_name}': " . $error->getMessage();
|
||||
$errorCount++;
|
||||
}
|
||||
}
|
||||
|
||||
if ($successCount > 0 && $errorCount === 0) {
|
||||
$message = "Đã xóa thành công {$successCount} domain!";
|
||||
} elseif ($successCount > 0) {
|
||||
$message = "Đã xóa thành công {$successCount} domain, {$errorCount} domain gặp lỗi.";
|
||||
} else {
|
||||
$message = 'Không thể xóa domain nào. Vui lòng kiểm tra lại.';
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'success' => $errorCount === 0,
|
||||
'message' => $message,
|
||||
'details' => ['success_count' => $successCount, 'error_count' => $errorCount, 'errors' => $errors],
|
||||
'url' => route('admin.domain.index'),
|
||||
]);
|
||||
}
|
||||
|
||||
private function domainActionButtons($domain): string
|
||||
{
|
||||
$editUrl = route('admin.domain.edit', ['id' => $domain->id]);
|
||||
$recordUrl = route('admin.domain.record', ['id' => $domain->id]);
|
||||
$deleteUrl = route('admin.domain.destroy', ['id' => $domain->id]);
|
||||
|
||||
return <<<HTML
|
||||
<a class="btn btn-sm btn-icon btn-primary" href="{$editUrl}">
|
||||
<svg class="icon" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none"/>
|
||||
<path d="M7 7h-1a2 2 0 0 0 -2 2v9a2 2 0 0 0 2 2h9a2 2 0 0 0 2 -2v-1"/>
|
||||
<path d="M20.385 6.585a2.1 2.1 0 0 0 -2.97 -2.97l-8.415 8.385v3h3l8.385 -8.415z"/>
|
||||
<path d="M16 5l3 3"/>
|
||||
</svg>
|
||||
<span class="sr-only">Edit</span>
|
||||
</a>
|
||||
<a class="btn btn-sm btn-icon btn-success" href="{$recordUrl}">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none"/>
|
||||
<path d="M9 5h-2a2 2 0 0 0 -2 2v12a2 2 0 0 0 2 2h10a2 2 0 0 0 2 -2v-12a2 2 0 0 0 -2 -2h-2"/>
|
||||
<path d="M9 3m0 2a2 2 0 0 1 2 -2h2a2 2 0 0 1 2 2v0a2 2 0 0 1 -2 2h-2a2 2 0 0 1 -2 -2z"/>
|
||||
<path d="M9 14h.01"/><path d="M9 17h.01"/><path d="M12 16l1 1l3 -3"/>
|
||||
</svg>
|
||||
<span class="sr-only">Records</span>
|
||||
</a>
|
||||
<a class="btn btn-sm btn-icon btn-icon__remove btn-danger"
|
||||
href="{$deleteUrl}"
|
||||
data-dt-single-action=""
|
||||
data-method="DELETE"
|
||||
data-confirmation-modal="true"
|
||||
data-bs-target="#modal-remove-tags"
|
||||
data-bs-toggle="modal"
|
||||
data-confirmation-modal-title="Confirm delete"
|
||||
data-confirmation-modal-message="Do you really want to delete this record?"
|
||||
data-confirmation-modal-button="Delete"
|
||||
data-confirmation-modal-cancel-button="Cancel">
|
||||
<svg class="icon" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none"/>
|
||||
<path d="M4 7l16 0"/><path d="M10 11l0 6"/><path d="M14 11l0 6"/>
|
||||
<path d="M5 7l1 12a2 2 0 0 0 2 2h8a2 2 0 0 0 2 -2l1 -12"/>
|
||||
<path d="M9 7v-3a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v3"/>
|
||||
</svg>
|
||||
<span class="sr-only">Delete</span>
|
||||
</a>
|
||||
HTML;
|
||||
}
|
||||
|
||||
private function clearDomainCaches($domain): void
|
||||
{
|
||||
try {
|
||||
Cache::forget("domain.{$domain->id}");
|
||||
Cache::forget("domain.{$domain->domain_name}");
|
||||
Cache::forget('domains.all');
|
||||
Cache::forget('domains.filtered');
|
||||
|
||||
if ($domain->users) {
|
||||
foreach ($domain->users as $user) {
|
||||
Cache::forget("user.{$user->id}.domains");
|
||||
}
|
||||
}
|
||||
|
||||
if ($domain->dns_manager_server_id) {
|
||||
Cache::forget("server.{$domain->dns_manager_server_id}.domains");
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
Log::warning('Failed to clear domain caches: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,312 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Backend;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Record\RecordRemoveRequest;
|
||||
use App\Repositories\DnsManager\Domain\DnsDomainRepositoryInterface;
|
||||
use App\Repositories\DnsManager\Record\DnsRecordRepositoryInterface;
|
||||
use App\Services\ServerService;
|
||||
use Exception;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class RecordController extends Controller
|
||||
{
|
||||
protected array $rules = [
|
||||
'A' => [
|
||||
'name' => 'required',
|
||||
'type' => 'required',
|
||||
'ttl' => 'required',
|
||||
'value' => 'required|ip|ipv4',
|
||||
'plesk_id' => 'nullable',
|
||||
],
|
||||
'AAAA' => [
|
||||
'name' => 'required',
|
||||
'type' => 'required',
|
||||
'ttl' => 'required',
|
||||
'value' => 'required|ip|ipv6',
|
||||
'plesk_id' => 'nullable',
|
||||
],
|
||||
'CNAME' => [
|
||||
'name' => 'required',
|
||||
'type' => 'required',
|
||||
'ttl' => 'required',
|
||||
'value' => 'required',
|
||||
'plesk_id' => 'nullable',
|
||||
],
|
||||
'MX' => [
|
||||
'name' => 'required',
|
||||
'type' => 'required',
|
||||
'ttl' => 'required',
|
||||
'value' => 'required',
|
||||
'priority' => 'required',
|
||||
'plesk_id' => 'nullable',
|
||||
],
|
||||
'TXT' => [
|
||||
'name' => 'required',
|
||||
'type' => 'required',
|
||||
'ttl' => 'required',
|
||||
'value' => 'required',
|
||||
'plesk_id' => 'nullable',
|
||||
],
|
||||
'CAA' => [
|
||||
'name' => 'required',
|
||||
'type' => 'required',
|
||||
'ttl' => 'required',
|
||||
'value' => 'required',
|
||||
'plesk_id' => 'nullable',
|
||||
],
|
||||
'SRV' => [
|
||||
'type' => 'required',
|
||||
'ttl' => 'required',
|
||||
'value' => 'required',
|
||||
'service_name' => 'required',
|
||||
'protocol' => 'required',
|
||||
'weight' => 'required',
|
||||
'port' => 'required',
|
||||
'priority' => 'required',
|
||||
'plesk_id' => 'nullable',
|
||||
],
|
||||
];
|
||||
|
||||
public function __construct(
|
||||
public DnsDomainRepositoryInterface $domainRepository,
|
||||
public DnsRecordRepositoryInterface $recordRepository,
|
||||
public ServerService $serverService
|
||||
) {}
|
||||
|
||||
public function index()
|
||||
{
|
||||
$title = 'All Records';
|
||||
return view('Backend.records.index', compact('title'));
|
||||
}
|
||||
|
||||
public function getAll()
|
||||
{
|
||||
$records = $this->recordRepository->filter([], ['domain'])->map(function ($record) {
|
||||
return [
|
||||
'id' => $record->id,
|
||||
'name' => Str::limit($record->name, 20, '...'),
|
||||
'type' => $record->type,
|
||||
'value' => Str::limit($record->value, 20, '...'),
|
||||
'domain' => $record->domain ? $record->domain->domain_name : '',
|
||||
'checkbox' => '<input class="form-check-input m-0 align-middle" value="' . $record->id . '" type="checkbox" aria-label="Select tag">',
|
||||
'created_at' => Carbon::parse($record->created_at)->format('Y-m-d H:i:s'),
|
||||
'action' => $this->recordActionButtons($record),
|
||||
];
|
||||
});
|
||||
|
||||
return response()->json(['data' => $records]);
|
||||
}
|
||||
|
||||
public function create(int $id)
|
||||
{
|
||||
$title = 'Add Records';
|
||||
return view('Backend.records.create', compact('title', 'id'));
|
||||
}
|
||||
|
||||
public function store(Request $request, int $id = 0)
|
||||
{
|
||||
$domain = $this->domainRepository->find($id);
|
||||
if (empty($domain)) {
|
||||
return response()->json(['success' => false, 'message' => 'These credentials do not match our records.']);
|
||||
}
|
||||
|
||||
$validated = Validator::make($request->all(), $this->rules[$request->get('type')] ?? []);
|
||||
|
||||
if ($validated->fails()) {
|
||||
return response()->json(['success' => false, 'message' => $validated->errors()->first()]);
|
||||
}
|
||||
|
||||
$request->merge(['dns_manager_domain_id' => $id, 'domain' => $domain->domain_name]);
|
||||
|
||||
if (empty($request->get('plesk_id'))) {
|
||||
$this->serverService->findServerByID($domain->dns_manager_server_id);
|
||||
$this->serverService->handlePayload($request->all());
|
||||
$record = $this->serverService->addRecord();
|
||||
|
||||
if (!empty($record) && $record['error']) {
|
||||
return response()->json(['success' => false, 'message' => $record['message'] ?? 'Failed to add record on server.']);
|
||||
}
|
||||
}
|
||||
|
||||
DB::beginTransaction();
|
||||
try {
|
||||
if (isset($record)) {
|
||||
$request->merge(['plesk_id' => $record['data']['id'] ?? 0]);
|
||||
}
|
||||
|
||||
$this->recordRepository->create($request->all());
|
||||
DB::commit();
|
||||
} catch (Exception $error) {
|
||||
DB::rollBack();
|
||||
return response()->json(['success' => false, 'message' => $error->getMessage()]);
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => 'Add record successfully',
|
||||
'url' => route('admin.domain.record', ['id' => $id]),
|
||||
]);
|
||||
}
|
||||
|
||||
public function edit(int $id = 0, int $record_id = 0)
|
||||
{
|
||||
$domain = $this->domainRepository->find($id);
|
||||
if (empty($domain)) {
|
||||
return back()->withErrors('These credentials do not match our records.');
|
||||
}
|
||||
|
||||
$record = $this->recordRepository->find($record_id);
|
||||
if (empty($record)) {
|
||||
return back()->withErrors('These credentials do not match our records.');
|
||||
}
|
||||
|
||||
$title = 'Edit Record';
|
||||
return view('Backend.records.edit', compact('title', 'record', 'id'));
|
||||
}
|
||||
|
||||
public function update(Request $request, int $id = 0, int $record_id = 0)
|
||||
{
|
||||
$domain = $this->domainRepository->find($id);
|
||||
if (empty($domain)) {
|
||||
return response()->json(['success' => false, 'message' => 'These credentials do not match our records.']);
|
||||
}
|
||||
|
||||
$record = $this->recordRepository->find($record_id);
|
||||
if (empty($record)) {
|
||||
return response()->json(['success' => false, 'message' => 'These credentials do not match our records.']);
|
||||
}
|
||||
|
||||
$validated = Validator::make($request->all(), $this->rules[$request->get('type')] ?? []);
|
||||
|
||||
if ($validated->fails()) {
|
||||
return response()->json(['success' => false, 'message' => $validated->errors()->first()]);
|
||||
}
|
||||
|
||||
$this->serverService->findServerByID($domain->dns_manager_server_id);
|
||||
$this->serverService->handlePayload($request->all());
|
||||
$updatedRecord = $this->serverService->updateRecord($record->plesk_id);
|
||||
|
||||
if (!empty($updatedRecord) && $updatedRecord['error']) {
|
||||
return response()->json(['success' => false, 'message' => $updatedRecord['message'] ?? 'Failed to update record on server.']);
|
||||
}
|
||||
|
||||
DB::beginTransaction();
|
||||
try {
|
||||
$this->recordRepository->update($record_id, $request->all());
|
||||
DB::commit();
|
||||
} catch (Exception $error) {
|
||||
DB::rollBack();
|
||||
return response()->json(['success' => false, 'message' => $error->getMessage()]);
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => 'Update record successfully',
|
||||
'url' => route('admin.domain.record', ['id' => $id]),
|
||||
]);
|
||||
}
|
||||
|
||||
public function destroy(int $id = 0)
|
||||
{
|
||||
$record = $this->recordRepository->findWithRelations($id, ['domain']);
|
||||
if (empty($record) || empty($record->domain)) {
|
||||
return response()->json(['success' => false, 'message' => 'These credentials do not match our records.']);
|
||||
}
|
||||
|
||||
$this->serverService->findServerByID($record->domain->dns_manager_server_id);
|
||||
$record_delete = $this->serverService->deleteRecord($record->plesk_id);
|
||||
|
||||
if (!empty($record_delete) && $record_delete['error']) {
|
||||
return response()->json(['success' => false, 'message' => $record_delete['message'] ?? 'Failed to delete record on server.']);
|
||||
}
|
||||
|
||||
DB::beginTransaction();
|
||||
try {
|
||||
$domainId = $record->dns_manager_domain_id;
|
||||
$this->recordRepository->delete($id);
|
||||
DB::commit();
|
||||
} catch (Exception $error) {
|
||||
DB::rollBack();
|
||||
return response()->json(['success' => false, 'message' => $error->getMessage()]);
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => 'Deleted record successfully',
|
||||
'url' => route('admin.domain.record', ['id' => $domainId]),
|
||||
]);
|
||||
}
|
||||
|
||||
public function destroyCustom(RecordRemoveRequest $request)
|
||||
{
|
||||
$request->validated();
|
||||
|
||||
$records = $this->recordRepository->findWhereIn('id', $request->get('ids'), ['domain']);
|
||||
|
||||
if (!$records) {
|
||||
return response()->json(['success' => false, 'message' => 'These credentials do not match our records.']);
|
||||
}
|
||||
|
||||
try {
|
||||
foreach ($records->all() as $record) {
|
||||
if (empty($record->domain)) continue;
|
||||
|
||||
$this->serverService->findServerByID($record->domain->dns_manager_server_id);
|
||||
$this->serverService->deleteRecord($record->plesk_id);
|
||||
$this->recordRepository->delete($record->id);
|
||||
}
|
||||
} catch (Exception $error) {
|
||||
return response()->json(['success' => false, 'message' => $error->getMessage()]);
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => 'Deleted successfully!',
|
||||
'url' => route('admin.record.index'),
|
||||
]);
|
||||
}
|
||||
|
||||
private function recordActionButtons($record): string
|
||||
{
|
||||
$domainId = $record->domain ? $record->domain->id : 0;
|
||||
$editUrl = route('admin.record.edit', ['id' => $domainId, 'record_id' => $record->id]);
|
||||
$deleteUrl = route('admin.record.destroy', ['id' => $record->id]);
|
||||
|
||||
return <<<HTML
|
||||
<a class="btn btn-sm btn-icon btn-primary" href="{$editUrl}">
|
||||
<svg class="icon" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none"/>
|
||||
<path d="M7 7h-1a2 2 0 0 0 -2 2v9a2 2 0 0 0 2 2h9a2 2 0 0 0 2 -2v-1"/>
|
||||
<path d="M20.385 6.585a2.1 2.1 0 0 0 -2.97 -2.97l-8.415 8.385v3h3l8.385 -8.415z"/>
|
||||
<path d="M16 5l3 3"/>
|
||||
</svg>
|
||||
<span class="sr-only">Edit</span>
|
||||
</a>
|
||||
<a class="btn btn-sm btn-icon btn-icon__remove btn-danger"
|
||||
href="{$deleteUrl}"
|
||||
data-dt-single-action=""
|
||||
data-method="DELETE"
|
||||
data-confirmation-modal="true"
|
||||
data-bs-target="#modal-remove-tags"
|
||||
data-bs-toggle="modal"
|
||||
data-confirmation-modal-title="Confirm delete"
|
||||
data-confirmation-modal-message="Do you really want to delete this record?"
|
||||
data-confirmation-modal-button="Delete"
|
||||
data-confirmation-modal-cancel-button="Cancel">
|
||||
<svg class="icon" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none"/>
|
||||
<path d="M4 7l16 0"/><path d="M10 11l0 6"/><path d="M14 11l0 6"/>
|
||||
<path d="M5 7l1 12a2 2 0 0 0 2 2h8a2 2 0 0 0 2 -2l1 -12"/>
|
||||
<path d="M9 7v-3a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v3"/>
|
||||
</svg>
|
||||
<span class="sr-only">Delete</span>
|
||||
</a>
|
||||
HTML;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,204 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Backend;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Server\ServerRemoveRequest;
|
||||
use App\Http\Requests\Server\ServerRequest;
|
||||
use App\Repositories\DnsManager\Server\DnsServerRepositoryInterface;
|
||||
use App\Services\ServerService;
|
||||
use Exception;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\Crypt;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
class ServerController extends Controller
|
||||
{
|
||||
public function __construct(
|
||||
public DnsServerRepositoryInterface $serverRepository,
|
||||
public ServerService $serverService
|
||||
) {}
|
||||
|
||||
public function index()
|
||||
{
|
||||
$title = 'Server Hosting Manager';
|
||||
return view('Backend.servers.index', compact('title'));
|
||||
}
|
||||
|
||||
public function getAll()
|
||||
{
|
||||
$servers = $this->serverRepository->getAll()->map(function ($server) {
|
||||
return [
|
||||
'id' => $server->id,
|
||||
'name' => $server->name,
|
||||
'ip' => $server->ip_address,
|
||||
'status' => $server->getStatus(),
|
||||
'checkbox' => '<input class="form-check-input m-0 align-middle" value="' . $server->id . '" type="checkbox" aria-label="Select tag">',
|
||||
'created_at' => Carbon::parse($server->created_at)->format('Y-m-d H:i:s'),
|
||||
'action' => $this->serverActionButtons($server),
|
||||
];
|
||||
});
|
||||
|
||||
return response()->json(['data' => $servers]);
|
||||
}
|
||||
|
||||
public function create()
|
||||
{
|
||||
$title = 'Add New Server Hosting';
|
||||
return view('Backend.servers.create', compact('title'));
|
||||
}
|
||||
|
||||
public function connect(ServerRequest $request)
|
||||
{
|
||||
$request->validated();
|
||||
|
||||
if (!$request->ajax()) {
|
||||
return response()->json(['success' => false, 'message' => 'Method not support']);
|
||||
}
|
||||
|
||||
$status = $this->serverService->checkConnection($request->all());
|
||||
|
||||
if ($status) {
|
||||
return response()->json(['success' => true, 'message' => 'Connection established successfully.']);
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'success' => false,
|
||||
'message' => 'Connection attempt failed. Please check your credentials or server settings.',
|
||||
]);
|
||||
}
|
||||
|
||||
public function store(ServerRequest $request)
|
||||
{
|
||||
$request->validated();
|
||||
|
||||
DB::beginTransaction();
|
||||
try {
|
||||
$data = $request->all();
|
||||
$data['password'] = Crypt::encryptString($request->password);
|
||||
|
||||
$this->serverRepository->create($data);
|
||||
DB::commit();
|
||||
} catch (Exception $error) {
|
||||
DB::rollBack();
|
||||
return response()->json(['success' => false, 'message' => $error->getMessage()]);
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => 'Created successfully!',
|
||||
'url' => route('admin.server.index'),
|
||||
]);
|
||||
}
|
||||
|
||||
public function edit(int $id)
|
||||
{
|
||||
$server = $this->serverRepository->find($id);
|
||||
if (!$server) {
|
||||
return back()->withErrors('Invalid Request');
|
||||
}
|
||||
|
||||
$title = 'Update Server Hosting';
|
||||
return view('Backend.servers.edit', compact('title', 'server'));
|
||||
}
|
||||
|
||||
public function update(ServerRequest $request, int $id)
|
||||
{
|
||||
$request->validated();
|
||||
|
||||
DB::beginTransaction();
|
||||
try {
|
||||
$data = $request->all();
|
||||
$data['password'] = Crypt::encryptString($request->password);
|
||||
|
||||
$this->serverRepository->update($id, $data);
|
||||
DB::commit();
|
||||
} catch (Exception $error) {
|
||||
DB::rollBack();
|
||||
return response()->json(['success' => false, 'message' => $error->getMessage()]);
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => 'Updated successfully!',
|
||||
'url' => route('admin.server.index'),
|
||||
]);
|
||||
}
|
||||
|
||||
public function destroy(int $id)
|
||||
{
|
||||
$server = $this->serverRepository->find($id);
|
||||
if (!$server) {
|
||||
return response()->json(['success' => false, 'message' => 'Invalid Request']);
|
||||
}
|
||||
|
||||
$this->serverRepository->delete($id);
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => 'Deleted successfully!',
|
||||
'url' => route('admin.server.index'),
|
||||
]);
|
||||
}
|
||||
|
||||
public function destroyCustom(ServerRemoveRequest $request)
|
||||
{
|
||||
$request->validated();
|
||||
|
||||
$servers = $this->serverRepository->findWhereIn('id', $request->get('ids'));
|
||||
|
||||
if (!$servers) {
|
||||
return response()->json(['success' => false, 'message' => 'Invalid Request']);
|
||||
}
|
||||
|
||||
foreach ($servers->all() as $server) {
|
||||
$this->serverRepository->delete($server->id);
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'message' => 'Deleted successfully!',
|
||||
'url' => route('admin.server.index'),
|
||||
]);
|
||||
}
|
||||
|
||||
private function serverActionButtons($server): string
|
||||
{
|
||||
$editUrl = route('admin.server.edit', ['id' => $server->id]);
|
||||
$deleteUrl = route('admin.server.destroy', ['id' => $server->id]);
|
||||
|
||||
return <<<HTML
|
||||
<a class="btn btn-sm btn-icon btn-primary" href="{$editUrl}">
|
||||
<svg class="icon" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
|
||||
<path d="M7 7h-1a2 2 0 0 0 -2 2v9a2 2 0 0 0 2 2h9a2 2 0 0 0 2 -2v-1"></path>
|
||||
<path d="M20.385 6.585a2.1 2.1 0 0 0 -2.97 -2.97l-8.415 8.385v3h3l8.385 -8.415z"></path>
|
||||
<path d="M16 5l3 3"></path>
|
||||
</svg>
|
||||
<span class="sr-only">Edit</span>
|
||||
</a>
|
||||
<a class="btn btn-sm btn-icon btn-icon__remove btn-danger"
|
||||
href="{$deleteUrl}"
|
||||
data-dt-single-action=""
|
||||
data-method="DELETE"
|
||||
data-confirmation-modal="true"
|
||||
data-bs-target="#modal-remove-tags"
|
||||
data-bs-toggle="modal"
|
||||
data-confirmation-modal-title="Confirm delete"
|
||||
data-confirmation-modal-message="Do you really want to delete this record?"
|
||||
data-confirmation-modal-button="Delete"
|
||||
data-confirmation-modal-cancel-button="Cancel">
|
||||
<svg class="icon" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
|
||||
<path d="M4 7l16 0"></path>
|
||||
<path d="M10 11l0 6"></path>
|
||||
<path d="M14 11l0 6"></path>
|
||||
<path d="M5 7l1 12a2 2 0 0 0 2 2h8a2 2 0 0 0 2 -2l1 -12"></path>
|
||||
<path d="M9 7v-3a1 1 0 0 1 1 -1h4a1 1 0 0 1 1 1v3"></path>
|
||||
</svg>
|
||||
<span class="sr-only">Delete</span>
|
||||
</a>
|
||||
HTML;
|
||||
}
|
||||
}
|
||||
@@ -720,7 +720,9 @@ class CustomerController extends Controller
|
||||
if (!$customer) {
|
||||
return back()->withErrors('Invalid request');
|
||||
}
|
||||
Auth::guard('users')->login($customer);
|
||||
// TODO: impersonation feature needs redesign for JWT — session login does not work with JWT guard
|
||||
// This is a legacy Livewire admin feature; will be removed when portal-admin migration is complete
|
||||
Auth::guard('client')->login($customer);
|
||||
|
||||
session()->put('admin_login_for_customer', true);
|
||||
|
||||
@@ -728,7 +730,7 @@ class CustomerController extends Controller
|
||||
}
|
||||
public function LogoutWithCustomer()
|
||||
{
|
||||
Auth::guard('users')->logout();
|
||||
Auth::guard('client')->logout();
|
||||
return redirect()->route('customer.index');
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ class LoginController extends Controller
|
||||
if (!$user)
|
||||
return back()->withErrors('Không tìm thấy thông tin người dùng');
|
||||
|
||||
if (Auth::guard('admins')->attempt(['username' => $request->username, 'password' => $request->password], $request->remember)) {
|
||||
if (Auth::guard('admin')->attempt(['username' => $request->username, 'password' => $request->password], $request->remember)) {
|
||||
if (\auth()->user()->status) {
|
||||
$token = \auth()->user()->createToken('access_token', ['*'], Carbon::now()->addDay())->plainTextToken;
|
||||
Cookie::queue('accessToken', $token, 24 * 60);
|
||||
|
||||
@@ -172,7 +172,7 @@ class OrderController extends Controller
|
||||
'discount_id' => $request->discount_id ?? 0,
|
||||
'amount' => $total + ($total * (10 / 100)),
|
||||
'payment_id' => $request->payment_id,
|
||||
'user_id' => auth()->guard('admins')->user()->id,
|
||||
'user_id' => auth()->guard('admin')->user()->id,
|
||||
'status' => $request->status,
|
||||
'client_ip' => $request->getClientIp()
|
||||
];
|
||||
|
||||
@@ -52,7 +52,7 @@ class SupportController extends Controller
|
||||
}
|
||||
$request->validated();
|
||||
|
||||
$request->merge(['user_id' => auth()->guard('admins')->id()]);
|
||||
$request->merge(['user_id' => auth()->guard('admin')->id()]);
|
||||
|
||||
DB::beginTransaction();
|
||||
try {
|
||||
|
||||
@@ -177,8 +177,8 @@ class TaskController extends Controller
|
||||
Log::create([
|
||||
'agent' => $request->userAgent(),
|
||||
'client_ip' => $request->getClientIp(),
|
||||
'username' => auth()->guard('admins')->user()->username,
|
||||
'description' => auth()->guard('admins')->user()->username . ": $request->action for VirtualMachine $request->product",
|
||||
'username' => auth()->guard('admin')->user()->username,
|
||||
'description' => auth()->guard('admin')->user()->username . ": $request->action for VirtualMachine $request->product",
|
||||
'customer_id' => $request->userid
|
||||
]);
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ class Host extends Controller
|
||||
$editUrl = route('package.host.edit', ['id' => $d->id]);
|
||||
$deleteBtn = '';
|
||||
|
||||
if (auth()->guard('admins')->user()->can("delete module vcenter")) {
|
||||
if (auth()->guard('admin')->user()->can("delete module vcenter")) {
|
||||
$deleteUrl = route('package.host.destroy', ['id' => $d->id]);
|
||||
$csrf = csrf_field();
|
||||
$method = method_field('delete');
|
||||
|
||||
@@ -61,14 +61,14 @@ if (!function_exists('format_day')) {
|
||||
if (!function_exists('customer')) {
|
||||
function customer()
|
||||
{
|
||||
return Auth::guard('users')->user();
|
||||
return Auth::guard('client')->user();
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('user')) {
|
||||
function user()
|
||||
{
|
||||
return Auth::guard('users')->user();
|
||||
return Auth::guard('client')->user();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ class IsLoginCheck
|
||||
*/
|
||||
public function handle(Request $request, Closure $next)
|
||||
{
|
||||
if (! auth()->guard('users')->check()) {
|
||||
if (! auth()->guard('client')->check()) {
|
||||
return $next($request);
|
||||
}
|
||||
return redirect()->route('home');
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests\Domain;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class DomainRemoveRequest extends FormRequest
|
||||
{
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'ids' => 'required|array|min:1',
|
||||
'ids.*' => 'required|integer|exists:dns_manager_domain,id',
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests\Domain;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class DomainRequest extends FormRequest
|
||||
{
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'domain_name' => 'required|string|max:255',
|
||||
'dns_manager_server_id' => 'required|integer|exists:dns_manager_servers,id',
|
||||
'user_id' => 'nullable|array',
|
||||
'user_id.*' => 'integer|exists:users,id',
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests\Record;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class RecordRemoveRequest extends FormRequest
|
||||
{
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'ids' => 'required|array|min:1',
|
||||
'ids.*' => 'required|integer|exists:dns_manager_ns,id',
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests\Server;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class ServerRemoveRequest extends FormRequest
|
||||
{
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'ids' => 'required|array|min:1',
|
||||
'ids.*' => 'required|integer|exists:dns_manager_servers,id',
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests\Server;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class ServerRequest extends FormRequest
|
||||
{
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'name' => 'required|string|max:255',
|
||||
'ip_address' => 'required|string|max:255',
|
||||
'username' => 'required|string|max:255',
|
||||
'password' => 'required|string|max:255',
|
||||
'status' => 'nullable|string|in:activated,Stopped',
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -26,7 +26,7 @@ class VNPayService
|
||||
$vnp_BankCode = $data['bankCode'] ?? '';
|
||||
$vnp_IpAddr = request()->ip();
|
||||
|
||||
$user = Auth::guard('client')->user() ?? Auth::guard('users')->user();
|
||||
$user = Auth::guard('client')->user();
|
||||
$userName = $user ? $user->fullname : 'Khách';
|
||||
|
||||
$isDeposit = isset($data['transaction_ref']);
|
||||
|
||||
@@ -6,12 +6,11 @@ use Illuminate\Database\Eloquent\Concerns\HasUuids;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||
use Laravel\Sanctum\HasApiTokens;
|
||||
use Tymon\JWTAuth\Contracts\JWTSubject;
|
||||
|
||||
class Customer extends Authenticatable implements JWTSubject
|
||||
{
|
||||
use HasFactory, HasApiTokens, HasUuids, SoftDeletes;
|
||||
use HasFactory, HasUuids, SoftDeletes;
|
||||
|
||||
protected $table = 'customers';
|
||||
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class DnsDomain extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $table = 'dns_manager_domain';
|
||||
|
||||
protected $fillable = [
|
||||
'domain_name',
|
||||
'user_id',
|
||||
'dns_manager_server_id',
|
||||
'is_created',
|
||||
'plesk_id',
|
||||
];
|
||||
|
||||
public function user()
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
|
||||
public function customer()
|
||||
{
|
||||
return $this->belongsToMany(Customer::class, 'dns_domain_user', 'domain_id', 'customer_id')->withTimestamps();
|
||||
}
|
||||
|
||||
public function server()
|
||||
{
|
||||
return $this->belongsTo(DnsServer::class, 'dns_manager_server_id', 'id');
|
||||
}
|
||||
|
||||
public function record()
|
||||
{
|
||||
return $this->hasMany(DnsRecord::class, 'dns_manager_domain_id', 'id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class DnsRecord extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $table = 'dns_manager_ns';
|
||||
|
||||
protected $fillable = [
|
||||
'dns_manager_domain_id',
|
||||
'name',
|
||||
'type',
|
||||
'type_valid',
|
||||
'priority',
|
||||
'weight',
|
||||
'port',
|
||||
'service_name',
|
||||
'protocol',
|
||||
'value',
|
||||
'ttl',
|
||||
'plesk_id',
|
||||
];
|
||||
|
||||
public function domain()
|
||||
{
|
||||
return $this->belongsTo(DnsDomain::class, 'dns_manager_domain_id', 'id');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class DnsServer extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $table = 'dns_manager_servers';
|
||||
|
||||
protected $fillable = [
|
||||
'name',
|
||||
'ip_address',
|
||||
'password',
|
||||
'username',
|
||||
'api_key',
|
||||
'status',
|
||||
];
|
||||
|
||||
public function getStatus(): string
|
||||
{
|
||||
return match ($this->attributes['status']) {
|
||||
'activated' => '<span class="badge bg-success text-success-fg">Activated</span>',
|
||||
'Stopped' => '<span class="badge bg-danger text-danger-fg">Stopped</span>',
|
||||
default => '<span class="badge bg-secondary">Unknown</span>',
|
||||
};
|
||||
}
|
||||
|
||||
protected function scopeIsActive($query)
|
||||
{
|
||||
return $query->where('status', 'activated');
|
||||
}
|
||||
}
|
||||
+1
-3
@@ -2,17 +2,15 @@
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Contracts\Auth\MustVerifyEmail;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||
use Illuminate\Notifications\Notifiable;
|
||||
use Laravel\Sanctum\HasApiTokens;
|
||||
use Spatie\Permission\Traits\HasRoles;
|
||||
use Tymon\JWTAuth\Contracts\JWTSubject;
|
||||
|
||||
class User extends Authenticatable implements JWTSubject
|
||||
{
|
||||
use HasApiTokens, HasFactory, Notifiable;
|
||||
use HasFactory, Notifiable;
|
||||
use HasRoles;
|
||||
|
||||
protected $table = 'user';
|
||||
|
||||
@@ -24,8 +24,8 @@ class CustomerObserver
|
||||
$this->logRepository->create([
|
||||
'agent' => request()->userAgent(),
|
||||
'client_ip' => request()->getClientIp(),
|
||||
'username' => auth()->guard('admins')->user()->username ?? 'System',
|
||||
'description' => (auth()->guard('admins')->user()->username ?? 'System') . " created new Customer with id: " . $customer->id,
|
||||
'username' => auth()->guard('admin')->user()->username ?? 'System',
|
||||
'description' => (auth()->guard('admin')->user()->username ?? 'System') . " created new Customer with id: " . $customer->id,
|
||||
'customer_id' => $customer->id
|
||||
]);
|
||||
}
|
||||
@@ -43,8 +43,8 @@ class CustomerObserver
|
||||
$this->logRepository->create([
|
||||
'agent' => request()->userAgent(),
|
||||
'client_ip' => request()->getClientIp(),
|
||||
'username' => auth()->guard('admins')->user()->username ?? 'System',
|
||||
'description' => (auth()->guard('admins')->user()->username ?? 'System') . " Modified Customer ID#" . $customer->id . " - #$attribute from $old_value to $value",
|
||||
'username' => auth()->guard('admin')->user()->username ?? 'System',
|
||||
'description' => (auth()->guard('admin')->user()->username ?? 'System') . " Modified Customer ID#" . $customer->id . " - #$attribute from $old_value to $value",
|
||||
'customer_id' => $customer->id
|
||||
]);
|
||||
}
|
||||
@@ -61,8 +61,8 @@ class CustomerObserver
|
||||
$this->logRepository->create([
|
||||
'agent' => request()->userAgent(),
|
||||
'client_ip' => request()->getClientIp(),
|
||||
'username' => auth()->guard('admins')->user()->username ?? 'System',
|
||||
'description' => (auth()->guard('admins')->user()->username ?? 'System') . " Deleted Customer ID#" . $customer->getOriginal('id'),
|
||||
'username' => auth()->guard('admin')->user()->username ?? 'System',
|
||||
'description' => (auth()->guard('admin')->user()->username ?? 'System') . " Deleted Customer ID#" . $customer->getOriginal('id'),
|
||||
'customer_id' => $customer->getOriginal('id')
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -19,8 +19,8 @@ class OrderObserver
|
||||
$this->logRepository->create([
|
||||
'agent' => request()->userAgent(),
|
||||
'client_ip' => request()->getClientIp(),
|
||||
'username' => auth()->guard('admins')->user()->username ?? 'System',
|
||||
'description' => (auth()->guard('admins')->user()->username ?? 'System') . " created new Order with Order id: " . $order->id,
|
||||
'username' => auth()->guard('admin')->user()->username ?? 'System',
|
||||
'description' => (auth()->guard('admin')->user()->username ?? 'System') . " created new Order with Order id: " . $order->id,
|
||||
'customer_id' => $order->customer_id
|
||||
]);
|
||||
}
|
||||
@@ -38,8 +38,8 @@ class OrderObserver
|
||||
$this->logRepository->create([
|
||||
'agent' => request()->userAgent(),
|
||||
'client_ip' => request()->getClientIp(),
|
||||
'username' => auth()->guard('admins')->user()->username ?? 'System',
|
||||
'description' => (auth()->guard('admins')->user()->username ?? 'System') . " Modified Order ID#" . $order->id . " - #$attribute from $old_value to $value",
|
||||
'username' => auth()->guard('admin')->user()->username ?? 'System',
|
||||
'description' => (auth()->guard('admin')->user()->username ?? 'System') . " Modified Order ID#" . $order->id . " - #$attribute from $old_value to $value",
|
||||
'customer_id' => $order->customer_id
|
||||
]);
|
||||
}
|
||||
@@ -56,8 +56,8 @@ class OrderObserver
|
||||
$this->logRepository->create([
|
||||
'agent' => request()->userAgent(),
|
||||
'client_ip' => request()->getClientIp(),
|
||||
'username' => auth()->guard('admins')->user()->username ?? 'System',
|
||||
'description' => (auth()->guard('admins')->user()->username ?? 'System') . " Deleted Order ID#" . $order->getOriginal('id'),
|
||||
'username' => auth()->guard('admin')->user()->username ?? 'System',
|
||||
'description' => (auth()->guard('admin')->user()->username ?? 'System') . " Deleted Order ID#" . $order->getOriginal('id'),
|
||||
'customer_id' => $order->getOriginal('customer_id')
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
namespace App\Providers;
|
||||
|
||||
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use Laravel\Passport\Passport;
|
||||
|
||||
class AuthServiceProvider extends ServiceProvider
|
||||
{
|
||||
@@ -13,9 +11,7 @@ class AuthServiceProvider extends ServiceProvider
|
||||
*
|
||||
* @var array<class-string, class-string>
|
||||
*/
|
||||
protected $policies = [
|
||||
// 'App\Models\Customer' => 'App\Policies\ModelPolicy',
|
||||
];
|
||||
protected $policies = [];
|
||||
|
||||
/**
|
||||
* Register any authentication / authorization services.
|
||||
@@ -25,9 +21,5 @@ class AuthServiceProvider extends ServiceProvider
|
||||
public function boot()
|
||||
{
|
||||
$this->registerPolicies();
|
||||
|
||||
Passport::tokensExpireIn(now()->addDays(15));
|
||||
Passport::refreshTokensExpireIn(now()->addDays(30));
|
||||
Passport::personalAccessTokensExpireIn(now()->addDays(30));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,6 +98,12 @@ use App\Repositories\VPS\VPSCachedRepository;
|
||||
use App\Repositories\VPS\VPSRepositoryInterface;
|
||||
use App\Repositories\Module\VirtualMachine\VirtualMachineRepository;
|
||||
use App\Repositories\Module\VirtualMachine\VirtualMachineRepositoryInterface;
|
||||
use App\Repositories\DnsManager\Domain\DnsDomainRepository;
|
||||
use App\Repositories\DnsManager\Domain\DnsDomainRepositoryInterface;
|
||||
use App\Repositories\DnsManager\Server\DnsServerRepository as DnsManagerServerRepository;
|
||||
use App\Repositories\DnsManager\Server\DnsServerRepositoryInterface as DnsManagerServerRepositoryInterface;
|
||||
use App\Repositories\DnsManager\Record\DnsRecordRepository;
|
||||
use App\Repositories\DnsManager\Record\DnsRecordRepositoryInterface;
|
||||
|
||||
class RepositoryProvider extends ServiceProvider
|
||||
{
|
||||
@@ -364,6 +370,11 @@ class RepositoryProvider extends ServiceProvider
|
||||
\App\Repositories\Api\Service\ServiceRepositoryInterface::class,
|
||||
\App\Repositories\Api\Service\ServiceRepository::class
|
||||
);
|
||||
|
||||
// DNS Manager
|
||||
$this->app->bind(DnsManagerServerRepositoryInterface::class, DnsManagerServerRepository::class);
|
||||
$this->app->bind(DnsDomainRepositoryInterface::class, DnsDomainRepository::class);
|
||||
$this->app->bind(DnsRecordRepositoryInterface::class, DnsRecordRepository::class);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -50,7 +50,12 @@ class RouteServiceProvider extends ServiceProvider
|
||||
->namespace($this->namespace)
|
||||
->group(base_path('routes/api.php'));
|
||||
|
||||
// 3. Web & Admin routes
|
||||
// 3. Admin Backend routes (DNS Manager)
|
||||
Route::middleware('web')
|
||||
->namespace($this->namespace)
|
||||
->group(base_path('routes/admin.php'));
|
||||
|
||||
// 4. Web routes
|
||||
Route::middleware('web')
|
||||
->namespace($this->namespace)
|
||||
->group(base_path('routes/web.php'));
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
<?php
|
||||
|
||||
namespace App\Repositories\DnsManager\Domain;
|
||||
|
||||
use App\Models\DnsDomain;
|
||||
use App\Repositories\BaseRepository;
|
||||
|
||||
class DnsDomainRepository extends BaseRepository implements DnsDomainRepositoryInterface
|
||||
{
|
||||
public function getModel(): string
|
||||
{
|
||||
return DnsDomain::class;
|
||||
}
|
||||
|
||||
public function findDomain(string $domain = '')
|
||||
{
|
||||
return $this->model->where('domain_name', $domain)->first();
|
||||
}
|
||||
|
||||
public function filter(array $data = [], array $relationships = [], string $order = 'id', array $select = ['*'])
|
||||
{
|
||||
$model = $this->model;
|
||||
|
||||
if (count($relationships)) {
|
||||
$model = $model->with($relationships);
|
||||
}
|
||||
|
||||
if (isset($data['q']) && $data['q']) {
|
||||
$model = $model->where('domain_name', 'like', '%' . $data['q'] . '%');
|
||||
}
|
||||
|
||||
if (isset($data['search']['value']) && $data['search']['value']) {
|
||||
$model = $model->where('domain_name', 'like', '%' . $data['search']['value'] . '%');
|
||||
}
|
||||
|
||||
if (isset($data['user_id']) && $data['user_id']) {
|
||||
$model = $model->whereHas('users', function ($query) use ($data) {
|
||||
$query->where('users.id', $data['user_id']);
|
||||
});
|
||||
}
|
||||
|
||||
if (isset($data['limit']) && !isset($data['page']) && $data['limit']) {
|
||||
$model = $model->take($data['limit']);
|
||||
}
|
||||
|
||||
if (isset($data['relations'])) {
|
||||
foreach ($data['relations'] as $key => $value) {
|
||||
$model = $model->whereHas($key, function ($query) use ($value) {
|
||||
if (isset($value['condition'])) {
|
||||
switch (strtoupper($value['condition'])) {
|
||||
case 'IN':
|
||||
$query->whereIn($value['key'], $value['value']);
|
||||
break;
|
||||
case 'NOTIN':
|
||||
$query->whereNotIn($value['key'], $value['value']);
|
||||
break;
|
||||
default:
|
||||
$query->where($value['key'], $value['condition'], $value['value']);
|
||||
}
|
||||
} else {
|
||||
$query->where($value['key'], $value['value']);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
$model = $model->select($select)->orderByDesc($order);
|
||||
|
||||
if (isset($data['start'])) {
|
||||
return $model->offset($data['start'])->limit($data['length'] ?? 10)->get();
|
||||
}
|
||||
|
||||
if (isset($data['page'])) {
|
||||
return $model->paginate($data['length'] ?? 12);
|
||||
}
|
||||
|
||||
return $model->get();
|
||||
}
|
||||
|
||||
public function findWhereIn(string $key, array $value = [])
|
||||
{
|
||||
return $this->model->whereIn($key, $value)->get();
|
||||
}
|
||||
|
||||
public function findWithRelations(int $id, array $relationships = [])
|
||||
{
|
||||
return $this->model->with($relationships)->find($id);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace App\Repositories\DnsManager\Domain;
|
||||
|
||||
use App\Repositories\BaseRepositoryInterface;
|
||||
|
||||
interface DnsDomainRepositoryInterface extends BaseRepositoryInterface
|
||||
{
|
||||
public function findDomain(string $domain = '');
|
||||
|
||||
public function filter(array $data = [], array $relationships = [], string $order = 'id', array $select = ['*']);
|
||||
|
||||
public function findWhereIn(string $key, array $value = []);
|
||||
|
||||
public function findWithRelations(int $id, array $relationships = []);
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
namespace App\Repositories\DnsManager\Record;
|
||||
|
||||
use App\Models\DnsRecord;
|
||||
use App\Repositories\BaseRepository;
|
||||
|
||||
class DnsRecordRepository extends BaseRepository implements DnsRecordRepositoryInterface
|
||||
{
|
||||
public function getModel(): string
|
||||
{
|
||||
return DnsRecord::class;
|
||||
}
|
||||
|
||||
public function findWithRelations(int $id, array $relationships = [])
|
||||
{
|
||||
return $this->model->with($relationships)->find($id);
|
||||
}
|
||||
|
||||
public function findWhereIn(string $key, array $value = [], array $relationships = [])
|
||||
{
|
||||
return $this->model->with($relationships)->whereIn($key, $value)->get();
|
||||
}
|
||||
|
||||
public function filter(array $data = [], array $relationships = [], string $order = 'id', array $select = ['*'])
|
||||
{
|
||||
$model = $this->model;
|
||||
|
||||
if (count($relationships)) {
|
||||
$model = $model->with($relationships);
|
||||
}
|
||||
|
||||
if (isset($data['q']) && $data['q']) {
|
||||
$model = $model->where('name', 'like', '%' . $data['q'] . '%');
|
||||
}
|
||||
|
||||
if (isset($data['limit']) && !isset($data['page']) && $data['limit']) {
|
||||
$model = $model->take($data['limit']);
|
||||
}
|
||||
|
||||
if (isset($data['relations'])) {
|
||||
foreach ($data['relations'] as $key => $value) {
|
||||
$model = $model->whereHas($key, function ($query) use ($value) {
|
||||
if (isset($value['condition'])) {
|
||||
switch (strtoupper($value['condition'])) {
|
||||
case 'IN':
|
||||
$query->whereIn($value['key'], $value['value']);
|
||||
break;
|
||||
case 'NOTIN':
|
||||
$query->whereNotIn($value['key'], $value['value']);
|
||||
break;
|
||||
default:
|
||||
$query->where($value['key'], $value['condition'], $value['value']);
|
||||
}
|
||||
} else {
|
||||
$query->where($value['key'], $value['value']);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
$model = $model->select($select)->orderByDesc($order);
|
||||
|
||||
if (isset($data['page'])) {
|
||||
return $model->paginate(12);
|
||||
}
|
||||
|
||||
return $model->get();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
namespace App\Repositories\DnsManager\Record;
|
||||
|
||||
use App\Repositories\BaseRepositoryInterface;
|
||||
|
||||
interface DnsRecordRepositoryInterface extends BaseRepositoryInterface
|
||||
{
|
||||
public function filter(array $data = [], array $relationships = [], string $order = 'id', array $select = ['*']);
|
||||
|
||||
public function findWithRelations(int $id, array $relationships = []);
|
||||
|
||||
public function findWhereIn(string $key, array $value = [], array $relationships = []);
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace App\Repositories\DnsManager\Server;
|
||||
|
||||
use App\Models\DnsServer;
|
||||
use App\Repositories\BaseRepository;
|
||||
|
||||
class DnsServerRepository extends BaseRepository implements DnsServerRepositoryInterface
|
||||
{
|
||||
public function getModel(): string
|
||||
{
|
||||
return DnsServer::class;
|
||||
}
|
||||
|
||||
public function getActived()
|
||||
{
|
||||
return $this->model->isActive()->get();
|
||||
}
|
||||
|
||||
public function findWhereIn(string $key, array $value = [])
|
||||
{
|
||||
return $this->model->whereIn($key, $value)->get();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace App\Repositories\DnsManager\Server;
|
||||
|
||||
use App\Repositories\BaseRepositoryInterface;
|
||||
|
||||
interface DnsServerRepositoryInterface extends BaseRepositoryInterface
|
||||
{
|
||||
public function getActived();
|
||||
|
||||
public function findWhereIn(string $key, array $value = []);
|
||||
}
|
||||
@@ -0,0 +1,341 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services;
|
||||
|
||||
use App\Facades\BaseHelperFacade as BaseHelper;
|
||||
use App\Models\DnsServer;
|
||||
use App\Repositories\DnsManager\Server\DnsServerRepositoryInterface;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
use Illuminate\Http\Client\RequestException;
|
||||
use Illuminate\Support\Facades\Crypt;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class ServerService
|
||||
{
|
||||
protected $server;
|
||||
|
||||
protected array $payload = [
|
||||
'host' => '',
|
||||
'type' => 'A',
|
||||
'value' => '',
|
||||
'opt' => '',
|
||||
'ttl' => 300,
|
||||
];
|
||||
|
||||
protected string $domain = '';
|
||||
|
||||
protected array $entry_points = [
|
||||
'auth' => ':8443/api/v2/auth/keys',
|
||||
'server' => ':8443/api/v2/server',
|
||||
'domain' => ':8443/api/v2/domains',
|
||||
'record' => ':8443/api/v2/dns/records',
|
||||
];
|
||||
|
||||
public function __construct(
|
||||
public DnsServerRepositoryInterface $serverRepository
|
||||
) {
|
||||
$this->server = $this->getServer();
|
||||
}
|
||||
|
||||
public function findServerByID(int $id): ?DnsServer
|
||||
{
|
||||
return $this->server = $this->serverRepository->find($id);
|
||||
}
|
||||
|
||||
public function handlePayload(array $data = []): static
|
||||
{
|
||||
$this->domain = $data['domain'] ?? '';
|
||||
$name = $data['name'] ?? '';
|
||||
|
||||
$this->payload = [
|
||||
'type' => $data['type'] ?? 'A',
|
||||
'host' => $name === '@' ? $this->domain : ($name . '.' . $this->domain),
|
||||
'value' => str_replace(["\r", "\n"], ' ', $data['value'] ?? ''),
|
||||
'ttl' => $data['ttl'] ?? 300,
|
||||
];
|
||||
|
||||
switch (strtoupper($this->payload['type'])) {
|
||||
case 'MX':
|
||||
$this->payload['opt'] = $data['priority'] ?? 0;
|
||||
break;
|
||||
|
||||
case 'SRV':
|
||||
$this->payload['host'] = sprintf('_%s._%s.%s', $data['service_name'], $data['protocol'], $this->domain);
|
||||
$this->payload['opt'] = sprintf('%d %d %d', $data['priority'] ?? 0, $data['weight'] ?? 50, $data['port'] ?? 21);
|
||||
break;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function addRecord(): array
|
||||
{
|
||||
if (empty($this->domain)) {
|
||||
return ['error' => true, 'message' => 'Invalid domain'];
|
||||
}
|
||||
|
||||
try {
|
||||
$response = Http::withoutVerifying()
|
||||
->withBasicAuth($this->server->username, Crypt::decryptString($this->server->password))
|
||||
->timeout(10)
|
||||
->post(
|
||||
BaseHelper::url($this->server->ip_address) . $this->entry_points['record'] . '?' . http_build_query(['domain' => $this->domain]),
|
||||
$this->payload
|
||||
)->throw();
|
||||
|
||||
$this->resetServer();
|
||||
|
||||
return $response->successful() && count($response->json())
|
||||
? ['error' => false, 'data' => $response->json()]
|
||||
: ['error' => true];
|
||||
} catch (RequestException $e) {
|
||||
Log::error($e->getMessage());
|
||||
return ['error' => true, 'message' => $e->getMessage()];
|
||||
}
|
||||
}
|
||||
|
||||
public function updateRecord(int $record_id = 0): array
|
||||
{
|
||||
if (empty($record_id)) {
|
||||
return ['error' => true, 'message' => 'Invalid request'];
|
||||
}
|
||||
|
||||
try {
|
||||
$response = Http::withoutVerifying()
|
||||
->withBasicAuth($this->server->username, Crypt::decryptString($this->server->password))
|
||||
->timeout(10)
|
||||
->put(
|
||||
BaseHelper::url($this->server->ip_address) . $this->entry_points['record'] . "/$record_id",
|
||||
$this->payload
|
||||
)->throw();
|
||||
|
||||
$this->resetServer();
|
||||
|
||||
return $response->successful() && count($response->json())
|
||||
? ['error' => false, 'data' => $response->json()]
|
||||
: ['error' => true];
|
||||
} catch (RequestException $e) {
|
||||
Log::error($e->getMessage());
|
||||
return ['error' => true, 'message' => $e->getMessage()];
|
||||
}
|
||||
}
|
||||
|
||||
public function deleteRecord(int $record_id = 0): array
|
||||
{
|
||||
if (empty($record_id)) {
|
||||
return ['error' => true, 'message' => 'Invalid request'];
|
||||
}
|
||||
|
||||
try {
|
||||
$response = Http::withoutVerifying()
|
||||
->withBasicAuth($this->server->username, Crypt::decryptString($this->server->password))
|
||||
->timeout(30)
|
||||
->delete(
|
||||
BaseHelper::url($this->server->ip_address) . $this->entry_points['record'] . "/$record_id"
|
||||
)->throw();
|
||||
|
||||
$this->resetServer();
|
||||
|
||||
return $response->successful() && count($response->json())
|
||||
? ['error' => false, 'data' => $response->json()]
|
||||
: ['error' => true];
|
||||
} catch (RequestException $e) {
|
||||
Log::error($e->getMessage());
|
||||
return ['error' => true, 'message' => $e->getMessage()];
|
||||
}
|
||||
}
|
||||
|
||||
public function checkConnection(array $data = []): bool
|
||||
{
|
||||
if (empty($data['username']) || empty($data['password']) || empty($data['ip_address'])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
$response = Http::withoutVerifying()
|
||||
->withBasicAuth($data['username'], $data['password'])
|
||||
->timeout(10)
|
||||
->get(BaseHelper::url($data['ip_address']) . $this->entry_points['server']);
|
||||
|
||||
return $response->successful();
|
||||
} catch (RequestException $e) {
|
||||
Log::error($e->getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public function getDomainInfo(string $domain = ''): array|false
|
||||
{
|
||||
if (empty($domain)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
$response = Http::withoutVerifying()
|
||||
->withBasicAuth($this->server->username, Crypt::decryptString($this->server->password))
|
||||
->timeout(10)
|
||||
->get(BaseHelper::url($this->server->ip_address) . $this->entry_points['domain'], ['name' => $domain]);
|
||||
|
||||
$this->resetServer();
|
||||
|
||||
if ($response->successful()) {
|
||||
$domains = $response->json();
|
||||
foreach ($domains as $domainInfo) {
|
||||
if (isset($domainInfo['name']) && $domainInfo['name'] === $domain) {
|
||||
return $domainInfo;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
} catch (RequestException $e) {
|
||||
Log::error($e->getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public function createDomain(array $data = []): array|false
|
||||
{
|
||||
if (empty($data)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$this->server) {
|
||||
$this->server = $this->serverRepository->find($data['dns_manager_server_id']);
|
||||
}
|
||||
|
||||
$param = [
|
||||
'name' => $data['domain_name'],
|
||||
'description' => '',
|
||||
'hosting_type' => 'virtual',
|
||||
'hosting_settings' => [
|
||||
'ftp_login' => str_replace('.', '_', $data['domain_name']),
|
||||
'ftp_password' => Str::random(12),
|
||||
],
|
||||
'ip_addresses' => ['103.42.58.124'],
|
||||
'ipv4' => ['103.42.58.124'],
|
||||
'plan' => ['name' => 'Default Domain'],
|
||||
];
|
||||
|
||||
try {
|
||||
$response = Http::withoutVerifying()
|
||||
->withBasicAuth($this->server->username, Crypt::decryptString($this->server->password))
|
||||
->timeout(30)
|
||||
->post(BaseHelper::url($this->server->ip_address) . $this->entry_points['domain'], $param);
|
||||
|
||||
$this->resetServer();
|
||||
$responseData = $response->json();
|
||||
|
||||
Log::info('Response Plesk API Created', ['data' => $responseData]);
|
||||
|
||||
if ($response->successful() && isset($responseData['id'], $responseData['guid'])) {
|
||||
return $responseData;
|
||||
}
|
||||
} catch (RequestException $e) {
|
||||
Log::error('Plesk domain creation failed', [
|
||||
'error' => $e->getMessage(),
|
||||
'response' => $e->response?->body(),
|
||||
'data' => $param,
|
||||
]);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function updateDomain(int $pleskDomainId, array $data = []): array|false
|
||||
{
|
||||
if (empty($pleskDomainId) || empty($data)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$this->server) {
|
||||
$this->server = $this->serverRepository->find($data['dns_manager_server_id']);
|
||||
}
|
||||
|
||||
$param = [
|
||||
'name' => $data['domain_name'],
|
||||
'description' => '',
|
||||
'hosting_type' => 'virtual',
|
||||
'hosting_settings' => [
|
||||
'ftp_login' => str_replace('.', '_', $data['domain_name']),
|
||||
'ftp_password' => Str::random(12),
|
||||
],
|
||||
'ip_addresses' => ['103.42.58.124'],
|
||||
'ipv4' => ['103.42.58.124'],
|
||||
'plan' => ['name' => 'Default Domain'],
|
||||
];
|
||||
|
||||
try {
|
||||
$response = Http::withoutVerifying()
|
||||
->withBasicAuth($this->server->username, Crypt::decryptString($this->server->password))
|
||||
->timeout(30)
|
||||
->put(BaseHelper::url($this->server->ip_address) . $this->entry_points['domain'] . "/{$pleskDomainId}", $param);
|
||||
|
||||
$this->resetServer();
|
||||
$responseData = $response->json();
|
||||
|
||||
Log::info('Response Plesk API Updated', ['data' => $responseData]);
|
||||
|
||||
if ($response->successful() && isset($responseData['id'], $responseData['guid'])) {
|
||||
return $responseData;
|
||||
}
|
||||
} catch (RequestException $e) {
|
||||
Log::error('Plesk domain update failed', [
|
||||
'error' => $e->getMessage(),
|
||||
'response' => $e->response?->body(),
|
||||
'data' => $param,
|
||||
]);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function removeDomain(int $pleskDomainId): bool
|
||||
{
|
||||
if (empty($this->server)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
$response = Http::withoutVerifying()
|
||||
->withBasicAuth($this->server->username, Crypt::decryptString($this->server->password))
|
||||
->timeout(30)
|
||||
->delete(BaseHelper::url($this->server->ip_address) . $this->entry_points['domain'] . "/{$pleskDomainId}");
|
||||
|
||||
$this->resetServer();
|
||||
|
||||
if ($response->successful()) {
|
||||
Log::info('Xoá domain thành công', ['plesk_id' => $pleskDomainId, 'status' => $response->status()]);
|
||||
return true;
|
||||
}
|
||||
|
||||
Log::error('Xoá domain thất bại', [
|
||||
'plesk_id' => $pleskDomainId,
|
||||
'status' => $response->status(),
|
||||
'response' => $response->body(),
|
||||
]);
|
||||
|
||||
return false;
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Exception khi xoá domain', ['plesk_id' => $pleskDomainId, 'error' => $e->getMessage()]);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public function addServerById(int $serverId): bool
|
||||
{
|
||||
$this->server = $this->serverRepository->find($serverId);
|
||||
return !empty($this->server);
|
||||
}
|
||||
|
||||
private function getServer(): ?DnsServer
|
||||
{
|
||||
return $this->serverRepository->getActived()->first();
|
||||
}
|
||||
|
||||
private function resetServer(): void
|
||||
{
|
||||
$this->server = null;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user