| Server IP : 35.80.110.71 / Your IP : 216.73.216.221 Web Server : Apache/2.4.58 (Ubuntu) System : Linux ip-172-31-21-44 6.17.0-1019-aws #19~24.04.1-Ubuntu SMP Tue Jun 23 18:53:06 UTC 2026 x86_64 User : ubuntu ( 1000) PHP Version : 8.3.31 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : OFF Directory : /var/www/client-portal-laravel/releases/20260626120707/routes/ |
Upload File : |
<?php
use App\Http\Controllers\Admin\CalendarWebhookController;
use App\Http\Controllers\Admin\SharedReportController;
use App\Http\Controllers\Api\DocumentationController;
use App\Http\Controllers\HealthController;
use App\Http\Controllers\InvitationController;
use App\Http\Controllers\NotificationHubController;
use App\Http\Controllers\SharedAuditController;
use App\Http\Controllers\SharedFindingController;
use App\Http\Controllers\ShareLinkController;
use App\Http\Controllers\SignatureController;
use App\Http\Controllers\Webhooks\ResendWebhookController;
use App\Http\Controllers\Webhooks\StripeWebhookController;
use App\Http\Controllers\Webhooks\WebsiteStripeWebhookController;
use Illuminate\Support\Facades\Route;
// Health check endpoints (no auth required, rate limited)
Route::middleware('throttle:10,1')->group(function () {
Route::get('/health', [HealthController::class, 'liveness'])->name('health.liveness');
Route::get('/health/ready', [HealthController::class, 'readiness'])->name('health.readiness');
});
// Note: Root "/" route is handled by domain-specific route files:
// - scopeforged.com → routes/marketing.php (marketing homepage)
// - portal.scopeforged.com → routes/portal.php (portal dashboard, requires auth)
// - admin.scopeforged.com → routes/admin/dashboard.php (admin dashboard, requires auth)
// Public share link routes
Route::prefix('share')->name('share.')->group(function () {
Route::get('{token}', [ShareLinkController::class, 'show'])->name('show');
Route::post('{token}/verify', [ShareLinkController::class, 'verifyPassword'])->name('verify-password');
Route::get('{token}/download', [ShareLinkController::class, 'download'])->name('download');
Route::get('{token}/preview', [ShareLinkController::class, 'preview'])->name('preview');
});
// Stripe webhook (CSRF exempt - handled in VerifyCsrfToken middleware)
Route::post('webhooks/stripe', [StripeWebhookController::class, 'handle'])
->name('webhooks.stripe')
->withoutMiddleware([\App\Http\Middleware\VerifyCsrfToken::class]);
// Websites Stripe webhook — dedicated endpoint per plan 270 §Phase 3 so
// the websites secret can rotate independently and the audit log is
// scoped to subscription lifecycle events.
Route::post('webhooks/websites/stripe', [WebsiteStripeWebhookController::class, 'handle'])
->name('webhooks.websites.stripe')
->withoutMiddleware([\App\Http\Middleware\VerifyCsrfToken::class]);
// Resend email webhook (CSRF exempt - uses signature verification)
Route::post('webhooks/resend', [ResendWebhookController::class, 'handle'])
->name('webhooks.resend')
->withoutMiddleware([\App\Http\Middleware\VerifyCsrfToken::class]);
// Google Calendar webhook (CSRF exempt - authenticated via channel token)
Route::post('webhooks/google-calendar', [CalendarWebhookController::class, 'google'])
->name('webhooks.google-calendar')
->withoutMiddleware([\App\Http\Middleware\VerifyCsrfToken::class]);
// Legacy dashboard route - redirect based on role
Route::get('/dashboard', function () {
if (auth()->user()->isAdmin()) {
return redirect()->route('admin.dashboard');
}
return redirect()->route('portal.dashboard');
})->middleware(['auth', 'verified'])->name('dashboard');
// API Documentation (Swagger UI)
Route::get('/api/docs', [DocumentationController::class, 'ui'])->name('api.docs.ui');
// Document Signing (public routes with token-based authentication)
Route::prefix('sign')->name('documents.sign.')->group(function () {
Route::get('/{token}', [SignatureController::class, 'show'])->name('show');
Route::post('/{token}', [SignatureController::class, 'sign'])->name('submit');
Route::post('/{token}/decline', [SignatureController::class, 'decline'])->name('decline');
Route::get('/{token}/confirmation', [SignatureController::class, 'confirmation'])->name('confirmation');
Route::get('/{token}/declined', [SignatureController::class, 'declinedConfirmation'])->name('declined-confirmation');
Route::get('/{token}/download', [SignatureController::class, 'downloadSignedCopy'])->name('download');
});
// Shared Reports (public routes with token-based authentication)
Route::prefix('r')->name('shared-reports.')->group(function () {
Route::get('/{token}', [SharedReportController::class, 'view'])->name('view');
Route::post('/{token}/password', [SharedReportController::class, 'view'])->name('password');
Route::get('/{token}/download/{format?}', [SharedReportController::class, 'download'])->name('download');
});
// Shared Audits (public routes with token-based authentication)
Route::prefix('audit')->name('shared-audit.')->group(function () {
Route::get('/{token}', [SharedAuditController::class, 'show'])->name('show');
Route::post('/{token}/verify', [SharedAuditController::class, 'verifyPassword'])->name('verify');
});
// Notification Unsubscribe (public routes with token-based authentication)
Route::prefix('unsubscribe')->name('notifications.unsubscribe.')->group(function () {
Route::get('/{token}', [NotificationHubController::class, 'unsubscribe'])->name('show');
Route::post('/{token}', [NotificationHubController::class, 'processUnsubscribe'])->name('process');
});
// Team Invitations (public routes for accepting invitations)
Route::prefix('invitation')->name('invitation.')->group(function () {
Route::get('/{token}', [InvitationController::class, 'show'])->name('show');
Route::post('/{token}/accept', [InvitationController::class, 'accept'])->name('accept');
});
// Shared Findings (public routes with token-based authentication)
Route::get('finding/{token}', [SharedFindingController::class, 'show'])->name('shared-finding.show');