some progress
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
|
||||
class AuthController extends Controller
|
||||
{
|
||||
/**
|
||||
* Create a new API token for the authenticated user.
|
||||
*/
|
||||
public function createToken(Request $request): JsonResponse
|
||||
{
|
||||
$validated = $request->validate([
|
||||
'token_name' => ['required', 'string', 'max:255'],
|
||||
]);
|
||||
|
||||
$token = $request->user()->createToken($validated['token_name']);
|
||||
|
||||
return response()->json([
|
||||
'token' => $token->plainTextToken,
|
||||
'type' => 'Bearer',
|
||||
], 201);
|
||||
}
|
||||
|
||||
/**
|
||||
* List all tokens for the authenticated user.
|
||||
*/
|
||||
public function tokens(Request $request): JsonResponse
|
||||
{
|
||||
$tokens = $request->user()->tokens()->get(['id', 'name', 'last_used_at', 'created_at']);
|
||||
|
||||
return response()->json([
|
||||
'data' => $tokens,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Revoke a specific token.
|
||||
*/
|
||||
public function revokeToken(Request $request, string $tokenId): JsonResponse
|
||||
{
|
||||
$deleted = $request->user()->tokens()->where('id', $tokenId)->delete();
|
||||
|
||||
if (!$deleted) {
|
||||
return response()->json([
|
||||
'message' => 'Token not found',
|
||||
], 404);
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'message' => 'Token revoked successfully',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Revoke all tokens for the authenticated user.
|
||||
*/
|
||||
public function revokeAllTokens(Request $request): JsonResponse
|
||||
{
|
||||
$request->user()->tokens()->delete();
|
||||
|
||||
return response()->json([
|
||||
'message' => 'All tokens revoked successfully',
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Api\BrokenLinksIndexRequest;
|
||||
use App\Models\Site;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class LinkController extends Controller
|
||||
{
|
||||
/**
|
||||
* Get broken links list for a site.
|
||||
*/
|
||||
public function index(BrokenLinksIndexRequest $request, Site $site): JsonResponse
|
||||
{
|
||||
// Ensure the site belongs to the authenticated user
|
||||
if ($site->user_id !== $request->user()->id) {
|
||||
return response()->json([
|
||||
'message' => 'Unauthorized',
|
||||
], 403);
|
||||
}
|
||||
|
||||
$perPage = $request->input('per_page', 50);
|
||||
$perPage = min($perPage, 100); // Max 100 per page
|
||||
|
||||
$brokenLinks = $site->brokenLinks()
|
||||
->orderBy('last_checked_at', 'desc')
|
||||
->paginate($perPage);
|
||||
|
||||
return response()->json($brokenLinks);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get broken links statistics for a site.
|
||||
*/
|
||||
public function stats(Request $request, Site $site): JsonResponse
|
||||
{
|
||||
// Ensure the site belongs to the authenticated user
|
||||
if ($site->user_id !== $request->user()->id) {
|
||||
return response()->json([
|
||||
'message' => 'Unauthorized',
|
||||
], 403);
|
||||
}
|
||||
|
||||
$totalBrokenLinks = $site->brokenLinks()->count();
|
||||
|
||||
$statusCodeBreakdown = $site->brokenLinks()
|
||||
->selectRaw('status_code, COUNT(*) as count')
|
||||
->groupBy('status_code')
|
||||
->orderBy('count', 'desc')
|
||||
->get();
|
||||
|
||||
return response()->json([
|
||||
'data' => [
|
||||
'total_broken_links' => $totalBrokenLinks,
|
||||
'status_code_breakdown' => $statusCodeBreakdown,
|
||||
],
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Site;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class SiteController extends Controller
|
||||
{
|
||||
/**
|
||||
* List all sites for the authenticated user.
|
||||
*/
|
||||
public function index(Request $request): JsonResponse
|
||||
{
|
||||
$sites = $request->user()
|
||||
->sites()
|
||||
->withCount(['uptimeChecks', 'sslCertificates', 'brokenLinks'])
|
||||
->orderBy('created_at', 'desc')
|
||||
->get();
|
||||
|
||||
return response()->json([
|
||||
'data' => $sites,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a specific site for the authenticated user.
|
||||
*/
|
||||
public function show(Request $request, Site $site): JsonResponse
|
||||
{
|
||||
// Ensure the site belongs to the authenticated user
|
||||
if ($site->user_id !== $request->user()->id) {
|
||||
return response()->json([
|
||||
'message' => 'Unauthorized',
|
||||
], 403);
|
||||
}
|
||||
|
||||
$site->loadCount(['uptimeChecks', 'sslCertificates', 'brokenLinks']);
|
||||
|
||||
return response()->json([
|
||||
'data' => $site,
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Api\SslHistoryRequest;
|
||||
use App\Models\Site;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class SslController extends Controller
|
||||
{
|
||||
/**
|
||||
* Get SSL certificate data for a site.
|
||||
*/
|
||||
public function show(Request $request, Site $site): JsonResponse
|
||||
{
|
||||
// Ensure the site belongs to the authenticated user
|
||||
if ($site->user_id !== $request->user()->id) {
|
||||
return response()->json([
|
||||
'message' => 'Unauthorized',
|
||||
], 403);
|
||||
}
|
||||
|
||||
$latestCertificate = $site->sslCertificates()
|
||||
->latest('checked_at')
|
||||
->first();
|
||||
|
||||
if (!$latestCertificate) {
|
||||
return response()->json([
|
||||
'message' => 'No SSL certificate data found',
|
||||
], 404);
|
||||
}
|
||||
|
||||
$daysUntilExpiry = null;
|
||||
$isExpiring = false;
|
||||
|
||||
if ($latestCertificate->expires_at) {
|
||||
$daysUntilExpiry = now()->diffInDays($latestCertificate->expires_at, false);
|
||||
$isExpiring = $daysUntilExpiry <= 30 && $daysUntilExpiry > 0;
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'data' => [
|
||||
'issuer' => $latestCertificate->issuer,
|
||||
'expires_at' => $latestCertificate->expires_at,
|
||||
'checked_at' => $latestCertificate->checked_at,
|
||||
'days_until_expiry' => $daysUntilExpiry ? (int) $daysUntilExpiry : null,
|
||||
'is_expiring_soon' => $isExpiring,
|
||||
'is_expired' => $daysUntilExpiry !== null && $daysUntilExpiry < 0,
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get SSL certificate history for a site.
|
||||
*/
|
||||
public function history(SslHistoryRequest $request, Site $site): JsonResponse
|
||||
{
|
||||
// Ensure the site belongs to the authenticated user
|
||||
if ($site->user_id !== $request->user()->id) {
|
||||
return response()->json([
|
||||
'message' => 'Unauthorized',
|
||||
], 403);
|
||||
}
|
||||
|
||||
$perPage = $request->input('per_page', 20);
|
||||
$perPage = min($perPage, 100); // Max 100 per page
|
||||
|
||||
$certificates = $site->sslCertificates()
|
||||
->orderBy('checked_at', 'desc')
|
||||
->paginate($perPage);
|
||||
|
||||
return response()->json($certificates);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Api\UptimeIndexRequest;
|
||||
use App\Models\Site;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class UptimeController extends Controller
|
||||
{
|
||||
/**
|
||||
* Get uptime history for a site (paginated).
|
||||
*/
|
||||
public function index(UptimeIndexRequest $request, Site $site): JsonResponse
|
||||
{
|
||||
// Ensure the site belongs to the authenticated user
|
||||
if ($site->user_id !== $request->user()->id) {
|
||||
return response()->json([
|
||||
'message' => 'Unauthorized',
|
||||
], 403);
|
||||
}
|
||||
|
||||
$perPage = $request->input('per_page', 50);
|
||||
$perPage = min($perPage, 100); // Max 100 per page
|
||||
|
||||
$uptimeChecks = $site->uptimeChecks()
|
||||
->orderBy('checked_at', 'desc')
|
||||
->paginate($perPage);
|
||||
|
||||
return response()->json($uptimeChecks);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get uptime statistics for a site.
|
||||
*/
|
||||
public function stats(Request $request, Site $site): JsonResponse
|
||||
{
|
||||
// Ensure the site belongs to the authenticated user
|
||||
if ($site->user_id !== $request->user()->id) {
|
||||
return response()->json([
|
||||
'message' => 'Unauthorized',
|
||||
], 403);
|
||||
}
|
||||
|
||||
$totalChecks = $site->uptimeChecks()->count();
|
||||
$successfulChecks = $site->uptimeChecks()
|
||||
->whereBetween('status_code', [200, 299])
|
||||
->count();
|
||||
|
||||
$uptimePercentage = $totalChecks > 0
|
||||
? round(($successfulChecks / $totalChecks) * 100, 2)
|
||||
: 0;
|
||||
|
||||
$averageResponseTime = $site->uptimeChecks()
|
||||
->avg('response_time_ms');
|
||||
|
||||
$latestCheck = $site->uptimeChecks()
|
||||
->latest('checked_at')
|
||||
->first();
|
||||
|
||||
return response()->json([
|
||||
'data' => [
|
||||
'total_checks' => $totalChecks,
|
||||
'successful_checks' => $successfulChecks,
|
||||
'uptime_percentage' => $uptimePercentage,
|
||||
'average_response_time_ms' => $averageResponseTime ? round($averageResponseTime, 2) : null,
|
||||
'latest_check' => $latestCheck,
|
||||
],
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,173 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\DnsRecord;
|
||||
use App\Models\Site;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\View\View;
|
||||
|
||||
class DnsRecordController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the DNS records for a site.
|
||||
*/
|
||||
public function index(Site $site): View
|
||||
{
|
||||
// Ensure the user owns the site
|
||||
if ($site->user_id !== Auth::id()) {
|
||||
abort(403, 'Unauthorized access to this site.');
|
||||
}
|
||||
|
||||
$dnsRecords = $site->dnsRecords()
|
||||
->orderBy('created_at', 'desc')
|
||||
->get();
|
||||
|
||||
return view('dns-records.index', compact('site', 'dnsRecords'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new DNS record.
|
||||
*/
|
||||
public function create(Site $site): View
|
||||
{
|
||||
// Ensure the user owns the site
|
||||
if ($site->user_id !== Auth::id()) {
|
||||
abort(403, 'Unauthorized access to this site.');
|
||||
}
|
||||
|
||||
$recordTypes = DnsRecord::getRecordTypes();
|
||||
|
||||
return view('dns-records.create', compact('site', 'recordTypes'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created DNS record in storage.
|
||||
*/
|
||||
public function store(Request $request, Site $site): RedirectResponse
|
||||
{
|
||||
// Ensure the user owns the site
|
||||
if ($site->user_id !== Auth::id()) {
|
||||
abort(403, 'Unauthorized access to this site.');
|
||||
}
|
||||
|
||||
$validated = $request->validate([
|
||||
'domain' => ['required', 'string', 'max:255'],
|
||||
'record_type' => ['required', 'string', 'in:A,AAAA,CNAME,MX,TXT,NS,SOA,PTR,SRV'],
|
||||
'expected_value' => ['nullable', 'string', 'max:1000'],
|
||||
'is_active' => ['boolean'],
|
||||
]);
|
||||
|
||||
// Check for duplicate record
|
||||
$exists = $site->dnsRecords()
|
||||
->where('domain', $validated['domain'])
|
||||
->where('record_type', $validated['record_type'])
|
||||
->exists();
|
||||
|
||||
if ($exists) {
|
||||
return back()
|
||||
->withInput()
|
||||
->withErrors(['domain' => "A {$validated['record_type']} record for {$validated['domain']} already exists for this site."]);
|
||||
}
|
||||
|
||||
$dnsRecord = $site->dnsRecords()->create([
|
||||
'domain' => $validated['domain'],
|
||||
'record_type' => $validated['record_type'],
|
||||
'expected_value' => $validated['expected_value'] ?? null,
|
||||
'is_active' => $validated['is_active'] ?? true,
|
||||
]);
|
||||
|
||||
return redirect()
|
||||
->route('dns-records.show', [$site, $dnsRecord])
|
||||
->with('success', 'DNS record created successfully.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified DNS record.
|
||||
*/
|
||||
public function show(Site $site, DnsRecord $dnsRecord): View
|
||||
{
|
||||
// Ensure the user owns the site and the DNS record belongs to the site
|
||||
if ($site->user_id !== Auth::id() || $dnsRecord->site_id !== $site->id) {
|
||||
abort(403, 'Unauthorized access to this DNS record.');
|
||||
}
|
||||
|
||||
return view('dns-records.show', compact('site', 'dnsRecord'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified DNS record.
|
||||
*/
|
||||
public function edit(Site $site, DnsRecord $dnsRecord): View
|
||||
{
|
||||
// Ensure the user owns the site and the DNS record belongs to the site
|
||||
if ($site->user_id !== Auth::id() || $dnsRecord->site_id !== $site->id) {
|
||||
abort(403, 'Unauthorized access to this DNS record.');
|
||||
}
|
||||
|
||||
$recordTypes = DnsRecord::getRecordTypes();
|
||||
|
||||
return view('dns-records.edit', compact('site', 'dnsRecord', 'recordTypes'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified DNS record in storage.
|
||||
*/
|
||||
public function update(Request $request, Site $site, DnsRecord $dnsRecord): RedirectResponse
|
||||
{
|
||||
// Ensure the user owns the site and the DNS record belongs to the site
|
||||
if ($site->user_id !== Auth::id() || $dnsRecord->site_id !== $site->id) {
|
||||
abort(403, 'Unauthorized access to this DNS record.');
|
||||
}
|
||||
|
||||
$validated = $request->validate([
|
||||
'domain' => ['required', 'string', 'max:255'],
|
||||
'record_type' => ['required', 'string', 'in:A,AAAA,CNAME,MX,TXT,NS,SOA,PTR,SRV'],
|
||||
'expected_value' => ['nullable', 'string', 'max:1000'],
|
||||
'is_active' => ['boolean'],
|
||||
]);
|
||||
|
||||
// Check for duplicate record (excluding current record)
|
||||
$exists = $site->dnsRecords()
|
||||
->where('domain', $validated['domain'])
|
||||
->where('record_type', $validated['record_type'])
|
||||
->where('id', '!=', $dnsRecord->id)
|
||||
->exists();
|
||||
|
||||
if ($exists) {
|
||||
return back()
|
||||
->withInput()
|
||||
->withErrors(['domain' => "A {$validated['record_type']} record for {$validated['domain']} already exists for this site."]);
|
||||
}
|
||||
|
||||
$dnsRecord->update([
|
||||
'domain' => $validated['domain'],
|
||||
'record_type' => $validated['record_type'],
|
||||
'expected_value' => $validated['expected_value'] ?? null,
|
||||
'is_active' => $validated['is_active'] ?? $dnsRecord->is_active,
|
||||
]);
|
||||
|
||||
return redirect()
|
||||
->route('dns-records.show', [$site, $dnsRecord])
|
||||
->with('success', 'DNS record updated successfully.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified DNS record from storage.
|
||||
*/
|
||||
public function destroy(Site $site, DnsRecord $dnsRecord): RedirectResponse
|
||||
{
|
||||
// Ensure the user owns the site and the DNS record belongs to the site
|
||||
if ($site->user_id !== Auth::id() || $dnsRecord->site_id !== $site->id) {
|
||||
abort(403, 'Unauthorized access to this DNS record.');
|
||||
}
|
||||
|
||||
$dnsRecord->delete();
|
||||
|
||||
return redirect()
|
||||
->route('dns-records.index', $site)
|
||||
->with('success', 'DNS record deleted successfully.');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,185 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\HealthCheck;
|
||||
use App\Models\Site;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\View\View;
|
||||
|
||||
class HealthCheckController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the health checks for a site.
|
||||
*/
|
||||
public function index(Site $site): View
|
||||
{
|
||||
// Ensure the user owns the site
|
||||
if ($site->user_id !== Auth::id()) {
|
||||
abort(403, 'Unauthorized access to this site.');
|
||||
}
|
||||
|
||||
$healthChecks = $site->healthChecks()
|
||||
->orderBy('created_at', 'desc')
|
||||
->get();
|
||||
|
||||
return view('health-checks.index', compact('site', 'healthChecks'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new health check.
|
||||
*/
|
||||
public function create(Site $site): View
|
||||
{
|
||||
// Ensure the user owns the site
|
||||
if ($site->user_id !== Auth::id()) {
|
||||
abort(403, 'Unauthorized access to this site.');
|
||||
}
|
||||
|
||||
return view('health-checks.create', compact('site'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created health check in storage.
|
||||
*/
|
||||
public function store(Request $request, Site $site): RedirectResponse
|
||||
{
|
||||
// Ensure the user owns the site
|
||||
if ($site->user_id !== Auth::id()) {
|
||||
abort(403, 'Unauthorized access to this site.');
|
||||
}
|
||||
|
||||
$validated = $request->validate([
|
||||
'endpoint' => ['required', 'string', 'max:255'],
|
||||
'expected_json_keys' => ['nullable', 'string'],
|
||||
'performance_threshold' => ['nullable', 'integer', 'min:1', 'max:60000'],
|
||||
'is_active' => ['boolean'],
|
||||
]);
|
||||
|
||||
// Convert comma-separated keys to array
|
||||
$expectedKeys = null;
|
||||
if (!empty($validated['expected_json_keys'])) {
|
||||
$expectedKeys = array_map(
|
||||
'trim',
|
||||
explode(',', $validated['expected_json_keys'])
|
||||
);
|
||||
}
|
||||
|
||||
// Check for duplicate endpoint
|
||||
$exists = $site->healthChecks()
|
||||
->where('endpoint', $validated['endpoint'])
|
||||
->exists();
|
||||
|
||||
if ($exists) {
|
||||
return back()
|
||||
->withInput()
|
||||
->withErrors(['endpoint' => 'This endpoint is already being monitored for this site.']);
|
||||
}
|
||||
|
||||
$healthCheck = $site->healthChecks()->create([
|
||||
'endpoint' => $validated['endpoint'],
|
||||
'expected_json_keys' => $expectedKeys,
|
||||
'performance_threshold' => $validated['performance_threshold'] ?? null,
|
||||
'is_active' => $validated['is_active'] ?? true,
|
||||
]);
|
||||
|
||||
return redirect()
|
||||
->route('health-checks.show', [$site, $healthCheck])
|
||||
->with('success', 'Health check created successfully.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified health check.
|
||||
*/
|
||||
public function show(Site $site, HealthCheck $healthCheck): View
|
||||
{
|
||||
// Ensure the user owns the site and the health check belongs to the site
|
||||
if ($site->user_id !== Auth::id() || $healthCheck->site_id !== $site->id) {
|
||||
abort(403, 'Unauthorized access to this health check.');
|
||||
}
|
||||
|
||||
return view('health-checks.show', compact('site', 'healthCheck'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified health check.
|
||||
*/
|
||||
public function edit(Site $site, HealthCheck $healthCheck): View
|
||||
{
|
||||
// Ensure the user owns the site and the health check belongs to the site
|
||||
if ($site->user_id !== Auth::id() || $healthCheck->site_id !== $site->id) {
|
||||
abort(403, 'Unauthorized access to this health check.');
|
||||
}
|
||||
|
||||
return view('health-checks.edit', compact('site', 'healthCheck'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified health check in storage.
|
||||
*/
|
||||
public function update(Request $request, Site $site, HealthCheck $healthCheck): RedirectResponse
|
||||
{
|
||||
// Ensure the user owns the site and the health check belongs to the site
|
||||
if ($site->user_id !== Auth::id() || $healthCheck->site_id !== $site->id) {
|
||||
abort(403, 'Unauthorized access to this health check.');
|
||||
}
|
||||
|
||||
$validated = $request->validate([
|
||||
'endpoint' => ['required', 'string', 'max:255'],
|
||||
'expected_json_keys' => ['nullable', 'string'],
|
||||
'performance_threshold' => ['nullable', 'integer', 'min:1', 'max:60000'],
|
||||
'is_active' => ['boolean'],
|
||||
]);
|
||||
|
||||
// Convert comma-separated keys to array
|
||||
$expectedKeys = null;
|
||||
if (!empty($validated['expected_json_keys'])) {
|
||||
$expectedKeys = array_map(
|
||||
'trim',
|
||||
explode(',', $validated['expected_json_keys'])
|
||||
);
|
||||
}
|
||||
|
||||
// Check for duplicate endpoint (excluding current health check)
|
||||
$exists = $site->healthChecks()
|
||||
->where('endpoint', $validated['endpoint'])
|
||||
->where('id', '!=', $healthCheck->id)
|
||||
->exists();
|
||||
|
||||
if ($exists) {
|
||||
return back()
|
||||
->withInput()
|
||||
->withErrors(['endpoint' => 'This endpoint is already being monitored for this site.']);
|
||||
}
|
||||
|
||||
$healthCheck->update([
|
||||
'endpoint' => $validated['endpoint'],
|
||||
'expected_json_keys' => $expectedKeys,
|
||||
'performance_threshold' => $validated['performance_threshold'] ?? null,
|
||||
'is_active' => $validated['is_active'] ?? $healthCheck->is_active,
|
||||
]);
|
||||
|
||||
return redirect()
|
||||
->route('health-checks.show', [$site, $healthCheck])
|
||||
->with('success', 'Health check updated successfully.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified health check from storage.
|
||||
*/
|
||||
public function destroy(Site $site, HealthCheck $healthCheck): RedirectResponse
|
||||
{
|
||||
// Ensure the user owns the site and the health check belongs to the site
|
||||
if ($site->user_id !== Auth::id() || $healthCheck->site_id !== $site->id) {
|
||||
abort(403, 'Unauthorized access to this health check.');
|
||||
}
|
||||
|
||||
$healthCheck->delete();
|
||||
|
||||
return redirect()
|
||||
->route('health-checks.index', $site)
|
||||
->with('success', 'Health check deleted successfully.');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Site;
|
||||
use App\Models\TcpPort;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class TcpPortController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*/
|
||||
public function index(Request $request, Site $site)
|
||||
{
|
||||
// Ensure the site belongs to the authenticated user
|
||||
if ($site->user_id !== Auth::id()) {
|
||||
abort(403);
|
||||
}
|
||||
|
||||
$tcpPorts = $site->tcpPorts()
|
||||
->orderBy('port')
|
||||
->paginate(20);
|
||||
|
||||
return view('tcp-ports.index', compact('site', 'tcpPorts'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*/
|
||||
public function create(Site $site)
|
||||
{
|
||||
// Ensure the site belongs to the authenticated user
|
||||
if ($site->user_id !== Auth::id()) {
|
||||
abort(403);
|
||||
}
|
||||
|
||||
$commonPorts = TcpPort::getCommonPorts();
|
||||
|
||||
return view('tcp-ports.create', compact('site', 'commonPorts'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*/
|
||||
public function store(Request $request, Site $site)
|
||||
{
|
||||
// Ensure the site belongs to the authenticated user
|
||||
if ($site->user_id !== Auth::id()) {
|
||||
abort(403);
|
||||
}
|
||||
|
||||
$validated = $request->validate([
|
||||
'port' => ['required', 'integer', 'min:1', 'max:65535'],
|
||||
'name' => ['nullable', 'string', 'max:255'],
|
||||
'is_active' => ['boolean'],
|
||||
]);
|
||||
|
||||
// Check if port already exists for this site
|
||||
$exists = $site->tcpPorts()
|
||||
->where('port', $validated['port'])
|
||||
->exists();
|
||||
|
||||
if ($exists) {
|
||||
return back()
|
||||
->withInput()
|
||||
->withErrors(['port' => 'This port is already being monitored for this site.']);
|
||||
}
|
||||
|
||||
$site->tcpPorts()->create([
|
||||
'port' => $validated['port'],
|
||||
'name' => $validated['name'] ?? null,
|
||||
'is_active' => $validated['is_active'] ?? true,
|
||||
]);
|
||||
|
||||
return redirect()
|
||||
->route('tcp-ports.index', $site)
|
||||
->with('success', 'TCP port added successfully.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*/
|
||||
public function show(Site $site, TcpPort $tcpPort)
|
||||
{
|
||||
// Ensure the port belongs to the site and user
|
||||
if ($tcpPort->site_id !== $site->id || $site->user_id !== Auth::id()) {
|
||||
abort(403);
|
||||
}
|
||||
|
||||
return view('tcp-ports.show', compact('site', 'tcpPort'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*/
|
||||
public function edit(Site $site, TcpPort $tcpPort)
|
||||
{
|
||||
// Ensure the port belongs to the site and user
|
||||
if ($tcpPort->site_id !== $site->id || $site->user_id !== Auth::id()) {
|
||||
abort(403);
|
||||
}
|
||||
|
||||
$commonPorts = TcpPort::getCommonPorts();
|
||||
|
||||
return view('tcp-ports.edit', compact('site', 'tcpPort', 'commonPorts'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*/
|
||||
public function update(Request $request, Site $site, TcpPort $tcpPort)
|
||||
{
|
||||
// Ensure the port belongs to the site and user
|
||||
if ($tcpPort->site_id !== $site->id || $site->user_id !== Auth::id()) {
|
||||
abort(403);
|
||||
}
|
||||
|
||||
$validated = $request->validate([
|
||||
'port' => ['required', 'integer', 'min:1', 'max:65535'],
|
||||
'name' => ['nullable', 'string', 'max:255'],
|
||||
'is_active' => ['boolean'],
|
||||
]);
|
||||
|
||||
// Check if port already exists for this site (excluding current)
|
||||
$exists = $site->tcpPorts()
|
||||
->where('port', $validated['port'])
|
||||
->where('id', '!=', $tcpPort->id)
|
||||
->exists();
|
||||
|
||||
if ($exists) {
|
||||
return back()
|
||||
->withInput()
|
||||
->withErrors(['port' => 'This port is already being monitored for this site.']);
|
||||
}
|
||||
|
||||
$tcpPort->update([
|
||||
'port' => $validated['port'],
|
||||
'name' => $validated['name'] ?? null,
|
||||
'is_active' => $validated['is_active'] ?? $tcpPort->is_active,
|
||||
]);
|
||||
|
||||
return redirect()
|
||||
->route('tcp-ports.index', $site)
|
||||
->with('success', 'TCP port updated successfully.');
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*/
|
||||
public function destroy(Site $site, TcpPort $tcpPort)
|
||||
{
|
||||
// Ensure the port belongs to the site and user
|
||||
if ($tcpPort->site_id !== $site->id || $site->user_id !== Auth::id()) {
|
||||
abort(403);
|
||||
}
|
||||
|
||||
$tcpPort->delete();
|
||||
|
||||
return redirect()
|
||||
->route('tcp-ports.index', $site)
|
||||
->with('success', 'TCP port deleted successfully.');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests\Api;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class BrokenLinksIndexRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'per_page' => ['nullable', 'integer', 'min:1', 'max:100'],
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests\Api;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class SslHistoryRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'per_page' => ['nullable', 'integer', 'min:1', 'max:100'],
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests\Api;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class UptimeIndexRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'per_page' => ['nullable', 'integer', 'min:1', 'max:100'],
|
||||
];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user