feat: Prepare Zemailnator for Dokploy deployment
- Add highly optimized Dockerfile with Nginx and PHP-FPM 8.4 - Add docker-compose.yml configured with Redis and MariaDB 10.11 - Implement entrypoint.sh and supervisord.conf for background workers - Refactor legacy IMAP scripts into scheduled Artisan Commands - Secure app by removing old routes with hardcoded basic auth credentials - Configure email attachments to use Laravel Storage instead of insecure public/tmp
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
<?php
|
||||
|
||||
use App\Http\Controllers\AppController;
|
||||
|
||||
use App\Http\Controllers\ImpersonationController;
|
||||
use App\Http\Controllers\WebhookController;
|
||||
use App\Http\Middleware\CheckPageSlug;
|
||||
@@ -22,11 +21,14 @@ use App\Livewire\Settings\Billing;
|
||||
use App\Livewire\Settings\Password;
|
||||
use App\Livewire\Settings\Profile;
|
||||
use App\Models\Email;
|
||||
use Illuminate\Support\Facades\Artisan;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Illuminate\Support\Facades\Request;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
Route::get('/health', function () {
|
||||
return response('OK', 200);
|
||||
});
|
||||
|
||||
Route::get('/', Home::class)->name('home');
|
||||
Route::get('/mailbox', Mailbox::class)->name('mailbox');
|
||||
Route::get('/mailbox/{email?}', [AppController::class, 'mailbox'])->name('mailboxFromURL');
|
||||
@@ -71,76 +73,12 @@ Route::middleware(['auth', 'verified', CheckUserBanned::class])->group(function
|
||||
Route::get('dashboard/compose-email', Dashboard::class)->name('dashboard.compose');
|
||||
Route::get('dashboard/support', Support::class)->name('dashboard.support');
|
||||
|
||||
// LEGACY: Old Stripe Cashier checkout route (deprecated - use unified payment system)
|
||||
Route::get('checkout/{plan}', function ($pricing_id) {
|
||||
$plans = config('app.plans');
|
||||
$pricingData = [];
|
||||
foreach ($plans as $plan) {
|
||||
$pricingData[] = $plan['pricing_id'];
|
||||
}
|
||||
|
||||
if (in_array($pricing_id, $pricingData)) {
|
||||
return auth()->user()
|
||||
->newSubscription('default', $pricing_id)
|
||||
->allowPromotionCodes()
|
||||
->checkout([
|
||||
'billing_address_collection' => 'required',
|
||||
'success_url' => route('checkout.success'),
|
||||
'cancel_url' => route('checkout.cancel'),
|
||||
]);
|
||||
|
||||
}
|
||||
abort(404);
|
||||
})->name('checkout');
|
||||
|
||||
// LEGACY: Payment status routes (used by both legacy and unified systems)
|
||||
Route::get('dashboard/success', [Dashboard::class, 'paymentStatus'])->name('checkout.success')->defaults('status', 'success');
|
||||
Route::get('dashboard/cancel', [Dashboard::class, 'paymentStatus'])->name('checkout.cancel')->defaults('status', 'cancel');
|
||||
|
||||
Route::get('dashboard/billing', fn () => auth()->user()->redirectToBillingPortal(route('dashboard')))->name('billing');
|
||||
|
||||
Route::get('0xdash/slink', function (Request $request) {
|
||||
$validUser = 'admin';
|
||||
$validPass = 'admin@9608'; // 🔐 Change this to something secure
|
||||
|
||||
if (! isset($_SERVER['PHP_AUTH_USER']) ||
|
||||
Request::server('PHP_AUTH_USER') !== $validUser ||
|
||||
Request::server('PHP_AUTH_PW') !== $validPass) {
|
||||
|
||||
header('WWW-Authenticate: Basic realm="Restricted Area"');
|
||||
header('HTTP/1.0 401 Unauthorized');
|
||||
echo 'Unauthorized';
|
||||
exit;
|
||||
}
|
||||
Artisan::call('storage:link');
|
||||
$output = Artisan::output();
|
||||
|
||||
return response()->json([
|
||||
'message' => trim($output),
|
||||
]);
|
||||
})->name('storageLink');
|
||||
|
||||
Route::get('0xdash/scache', function (Request $request) {
|
||||
$validUser = 'admin';
|
||||
$validPass = 'admin@9608'; // 🔐 Change this to something secure
|
||||
|
||||
if (! isset($_SERVER['PHP_AUTH_USER']) ||
|
||||
Request::server('PHP_AUTH_USER') !== $validUser ||
|
||||
Request::server('PHP_AUTH_PW') !== $validPass) {
|
||||
|
||||
header('WWW-Authenticate: Basic realm="Restricted Area"');
|
||||
header('HTTP/1.0 401 Unauthorized');
|
||||
echo 'Unauthorized';
|
||||
exit;
|
||||
}
|
||||
Artisan::call('cache:clear');
|
||||
$output = Artisan::output();
|
||||
|
||||
return response()->json([
|
||||
'message' => trim($output),
|
||||
]);
|
||||
})->name('cacheClear');
|
||||
|
||||
// Impersonation Routes
|
||||
Route::prefix('impersonation')->name('impersonation.')->group(function (): void {
|
||||
Route::post('/stop', [ImpersonationController::class, 'stop'])->name('stop');
|
||||
|
||||
Reference in New Issue
Block a user