Files
ladill-hosting/routes/web.php
T
isaaccladandClaude Opus 4.8 a754e8068b Add public product landing page at /
Serve a marketing landing page at the site root via ProductLandingController
instead of redirecting straight to login, with config/product_landing.php and
product views.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-11 07:05:51 +00:00

141 lines
13 KiB
PHP

<?php
use App\Http\Controllers\ProductLandingController;
use App\Http\Controllers\Auth\SsoLoginController;
use App\Http\Controllers\Hosting\AccountController;
use App\Http\Controllers\Hosting\AfiaController;
use App\Http\Controllers\Hosting\DeveloperController;
use App\Http\Controllers\Hosting\HostingController;
use App\Http\Controllers\Hosting\HostingPanelController;
use App\Http\Controllers\Hosting\HostingProductController;
use App\Http\Controllers\Hosting\HostingTerminalSessionController;
use App\Http\Controllers\Hosting\OverviewController;
use App\Http\Controllers\Hosting\SearchController;
use App\Http\Controllers\Hosting\TeamController;
use App\Http\Controllers\NotificationController;
use Illuminate\Support\Facades\Route;
$serversApp = fn (string $path = ''): string => 'https://'.config('app.servers_domain').($path !== '' ? '/'.ltrim($path, '/') : '');
// Ladill Hosting — authenticated app for buying + managing hosting (hosting.ladill.com).
Route::get('/', [ProductLandingController::class, 'show'])->name('hosting.landing');
Route::get('/login', [SsoLoginController::class, 'connect'])->name('login');
Route::get('/sso/connect', [SsoLoginController::class, 'connect'])->name('sso.connect');
Route::get('/sso/callback', [SsoLoginController::class, 'callback'])->name('sso.callback');
Route::post('/logout', [SsoLoginController::class, 'logout'])->name('logout');
Route::get('/sso/logout-bridge', [SsoLoginController::class, 'logoutBridge'])->name('sso.logout-bridge');
Route::get('/sso/logout-frontchannel', [SsoLoginController::class, 'frontchannelLogout'])->name('sso.logout-frontchannel');
Route::get('/signed-out', fn () => auth()->check() ? redirect()->route('hosting.dashboard') : view('hosting.signed-out'))->name('hosting.signed-out');
Route::middleware(['auth'])->group(function () use ($serversApp) {
Route::get('/notifications', [NotificationController::class, 'index'])->name('notifications.index');
Route::get('/notifications/unread', [NotificationController::class, 'unread'])->name('notifications.unread');
Route::post('/notifications/{id}/read', [NotificationController::class, 'markAsRead'])->name('notifications.mark-read');
Route::post('/notifications/mark-all-read', [NotificationController::class, 'markAllAsRead'])->name('notifications.mark-all-read');
Route::get('/search', SearchController::class)->name('hosting.search');
Route::get('/dashboard', [OverviewController::class, 'index'])->name('hosting.dashboard');
Route::redirect('/hosting', '/dashboard')->name('hosting.index');
Route::get('/hosting/accounts', [OverviewController::class, 'accounts'])->name('hosting.accounts.index');
Route::get('/hosting/single-domain', [HostingProductController::class, 'singleDomain'])->name('hosting.single-domain');
Route::get('/hosting/multi-domain', [HostingProductController::class, 'multiDomain'])->name('hosting.multi-domain');
Route::get('/hosting/wordpress', [HostingProductController::class, 'wordpress'])->name('hosting.wordpress');
// VPS/dedicated belong to Ladill Servers (servers.ladill.com), not shared hosting.
Route::any('/hosting/vps', fn () => redirect()->away($serversApp('vps'), 307));
Route::any('/hosting/dedicated', fn () => redirect()->away($serversApp('dedicated'), 307));
Route::any('/hosting/servers', fn () => redirect()->away($serversApp('vps'), 307));
Route::any('/hosting/orders/{order}/panel/{path?}', function (int $order, ?string $path = null) use ($serversApp) {
$suffix = $path !== null && $path !== '' ? '/'.$path : '';
$qs = request()->getQueryString();
return redirect()->away($serversApp('orders/'.$order.'/panel'.$suffix).($qs ? '?'.$qs : ''), 307);
})->where('path', '.*');
Route::get('/hosting/accounts/{account}', [HostingProductController::class, 'showAccount'])->name('hosting.accounts.show')->where('account', '[0-9]+');
Route::post('/hosting/accounts/{account}/plan-change', [HostingProductController::class, 'changeAccountPlan'])->name('hosting.accounts.plan-change')->where('account', '[0-9]+');
Route::post('/hosting/accounts/{account}/renew', [HostingProductController::class, 'renewAccount'])->name('hosting.accounts.renew')->where('account', '[0-9]+');
Route::get('/hosting/accounts/{account}/renew/callback', [HostingProductController::class, 'renewAccountCallback'])->name('hosting.accounts.renew.callback')->where('account', '[0-9]+');
Route::get('/hosting/orders/{order}', [HostingProductController::class, 'show'])->name('hosting.orders.show');
Route::post('/hosting/orders', [HostingProductController::class, 'store'])->name('hosting.orders.store');
Route::post('/hosting/orders/{order}/cancel', [HostingProductController::class, 'cancel'])->name('hosting.orders.cancel');
Route::prefix('hosting/panel/{account}')->where(['account' => '[0-9]+'])->group(function () {
Route::get('/', [HostingPanelController::class, 'index'])->name('hosting.panel.index');
Route::get('/files', [HostingPanelController::class, 'fileManager'])->name('hosting.panel.files');
Route::get('/files/api', [HostingPanelController::class, 'fileManagerApi'])->name('hosting.panel.files.api');
Route::get('/files/read', [HostingPanelController::class, 'readFile'])->name('hosting.panel.files.read');
Route::post('/files/save', [HostingPanelController::class, 'saveFile'])->name('hosting.panel.files.save');
Route::post('/files/create', [HostingPanelController::class, 'createFile'])->name('hosting.panel.files.create');
Route::post('/files/delete', [HostingPanelController::class, 'deleteFile'])->name('hosting.panel.files.delete');
Route::post('/files/rename', [HostingPanelController::class, 'renameFile'])->name('hosting.panel.files.rename');
Route::post('/files/upload', [HostingPanelController::class, 'uploadFile'])->name('hosting.panel.files.upload');
Route::post('/files/upload/init', [HostingPanelController::class, 'initChunkedUpload'])->name('hosting.panel.files.upload.init');
Route::post('/files/upload/chunk', [HostingPanelController::class, 'uploadChunk'])->name('hosting.panel.files.upload.chunk');
Route::post('/files/upload/finalize', [HostingPanelController::class, 'finalizeChunkedUpload'])->name('hosting.panel.files.upload.finalize');
Route::post('/files/extract', [HostingPanelController::class, 'extractFile'])->name('hosting.panel.files.extract');
Route::post('/files/bulk-delete', [HostingPanelController::class, 'bulkDelete'])->name('hosting.panel.files.bulk-delete');
Route::post('/files/bulk-move', [HostingPanelController::class, 'bulkMove'])->name('hosting.panel.files.bulk-move');
Route::post('/files/bulk-copy', [HostingPanelController::class, 'bulkCopy'])->name('hosting.panel.files.bulk-copy');
Route::post('/files/bulk-compress', [HostingPanelController::class, 'bulkCompress'])->name('hosting.panel.files.bulk-compress');
Route::post('/files/chmod', [HostingPanelController::class, 'chmodFile'])->name('hosting.panel.files.chmod');
Route::get('/databases', [HostingPanelController::class, 'databases'])->name('hosting.panel.databases');
Route::post('/databases', [HostingPanelController::class, 'createDatabase'])->name('hosting.panel.databases.create');
Route::delete('/databases/{database}', [HostingPanelController::class, 'deleteDatabase'])->name('hosting.panel.databases.delete');
Route::post('/databases/{database}/reset-password', [HostingPanelController::class, 'resetDatabasePassword'])->name('hosting.panel.databases.reset-password');
Route::get('/domains', [HostingPanelController::class, 'domains'])->name('hosting.panel.domains');
Route::post('/domains', [HostingPanelController::class, 'addDomain'])->name('hosting.panel.domains.add');
Route::delete('/domains/{site}', [HostingPanelController::class, 'removeDomain'])->name('hosting.panel.domains.remove');
Route::get('/settings', [HostingPanelController::class, 'settings'])->name('hosting.panel.settings');
Route::post('/settings/password', [HostingPanelController::class, 'changePassword'])->name('hosting.panel.settings.password');
Route::post('/settings/ssh-key', [HostingPanelController::class, 'saveSshKey'])->name('hosting.panel.settings.ssh-key');
Route::delete('/settings/ssh-key', [HostingPanelController::class, 'deleteSshKey'])->name('hosting.panel.settings.ssh-key.destroy');
Route::get('/terminal', [HostingPanelController::class, 'terminal'])->name('hosting.panel.terminal');
Route::post('/terminal/run', [HostingPanelController::class, 'runTerminalCommand'])->name('hosting.panel.terminal.run');
Route::post('/terminal/sessions', [HostingTerminalSessionController::class, 'start'])->name('hosting.panel.terminal.sessions.start');
Route::get('/terminal/sessions/{session}', [HostingTerminalSessionController::class, 'read'])->name('hosting.panel.terminal.sessions.read');
Route::post('/terminal/sessions/{session}/input', [HostingTerminalSessionController::class, 'input'])->name('hosting.panel.terminal.sessions.input');
Route::post('/terminal/sessions/{session}/resize', [HostingTerminalSessionController::class, 'resize'])->name('hosting.panel.terminal.sessions.resize');
Route::delete('/terminal/sessions/{session}', [HostingTerminalSessionController::class, 'close'])->name('hosting.panel.terminal.sessions.close');
Route::get('/php', [HostingPanelController::class, 'phpConfig'])->name('hosting.panel.php');
Route::post('/php/version', [HostingPanelController::class, 'changePhpVersion'])->name('hosting.panel.php.version');
Route::post('/php/settings', [HostingPanelController::class, 'savePhpSettings'])->name('hosting.panel.php.settings');
Route::get('/ssl', [HostingPanelController::class, 'ssl'])->name('hosting.panel.ssl');
Route::post('/ssl/{site}', [HostingPanelController::class, 'requestSsl'])->name('hosting.panel.ssl.request');
Route::get('/cron', [HostingPanelController::class, 'cronJobs'])->name('hosting.panel.cron');
Route::post('/cron', [HostingPanelController::class, 'addCronJob'])->name('hosting.panel.cron.add');
Route::delete('/cron', [HostingPanelController::class, 'deleteCronJob'])->name('hosting.panel.cron.delete');
Route::get('/logs', [HostingPanelController::class, 'logs'])->name('hosting.panel.logs');
Route::post('/logs/clear', [HostingPanelController::class, 'clearLogs'])->name('hosting.panel.logs.clear');
Route::get('/apps', [HostingPanelController::class, 'apps'])->name('hosting.panel.apps');
Route::post('/apps/install', [HostingPanelController::class, 'installApp'])->name('hosting.panel.apps.install');
Route::get('/apps/{installation}/progress', [HostingPanelController::class, 'installationProgress'])->name('hosting.panel.apps.progress');
Route::delete('/apps/{site}/delete', [HostingPanelController::class, 'deleteApp'])->name('hosting.panel.apps.delete');
});
Route::get('/hosting/legacy/{hostingOrder}', [HostingController::class, 'show'])->name('hosting.legacy.show');
Route::post('/hosting/legacy/{hostingOrder}/renew', [HostingController::class, 'renew'])->name('hosting.legacy.renew');
Route::post('/hosting/legacy/{hostingOrder}/reset-panel-password', [HostingController::class, 'resetPanelPassword'])->name('hosting.legacy.reset-panel-password');
Route::delete('/hosting/legacy/{hostingOrder}', [HostingController::class, 'destroy'])->name('hosting.legacy.destroy');
Route::get('/account/wallet', [AccountController::class, 'wallet'])->name('account.wallet');
Route::get('/account/billing', [AccountController::class, 'billing'])->name('account.billing');
Route::get('/account/settings', [AccountController::class, 'settings'])->name('account.settings');
Route::put('/account/settings', [AccountController::class, 'updateSettings'])->name('account.settings.update');
Route::get('/account/team', [TeamController::class, 'index'])->name('account.team');
Route::post('/account/team', [TeamController::class, 'store'])->name('account.team.store');
Route::patch('/account/team/{member}/role', [TeamController::class, 'updateRole'])->name('account.team.role');
Route::delete('/account/team/{member}', [TeamController::class, 'destroy'])->name('account.team.destroy');
Route::post('/account/switch', [TeamController::class, 'switchAccount'])->name('account.switch');
Route::get('/account/developers', [DeveloperController::class, 'index'])->name('account.developers');
Route::post('/account/developers', [DeveloperController::class, 'store'])->name('account.developers.store');
Route::delete('/account/developers/{token}', [DeveloperController::class, 'destroy'])->whereNumber('token')->name('account.developers.destroy');
Route::post('/afia/chat', [AfiaController::class, 'chat'])->name('hosting.afia.chat');
});