name('locale.update'); // Temporary, read-only endpoint for validating Kodular JSON parsing. Route::get('/tasks', [TestTaskController::class, 'index']) ->middleware(AuthenticateEarnApiToken::class.':tasks:read,tasks') ->withoutMiddleware([ EncryptCookies::class, AddQueuedCookiesToResponse::class, StartSession::class, ShareErrorsFromSession::class, PreventRequestForgery::class, SetLocale::class, ]) ->name('test-tasks.index'); Route::view('/', 'welcome')->name('home'); Route::get('/earn', function () { $tasksPerUsd = (int) config('earn.tasks_per_usd'); $minimumPayoutUsd = (int) config('earn.minimum_payout_usd'); return view('earn', [ 'tasksPerUsd' => $tasksPerUsd, 'minimumPayoutUsd' => $minimumPayoutUsd, 'minimumPayoutTasks' => $tasksPerUsd * $minimumPayoutUsd, ]); })->name('earn'); Route::prefix('earn')->name('earn.')->group(function (): void { Route::get('/terms', [EarnLegalPageController::class, 'terms'])->name('terms'); Route::get('/privacy', [EarnLegalPageController::class, 'privacy'])->name('privacy'); Route::middleware('guest:earn')->group(function (): void { Route::get('/login', [EarnAuthController::class, 'loginForm'])->name('login'); Route::post('/login', [EarnAuthController::class, 'login'])->middleware('throttle:10,1')->name('login.store'); Route::get('/register', [EarnAuthController::class, 'registerForm'])->name('register'); Route::post('/register', [EarnAuthController::class, 'register'])->middleware('throttle:6,1')->name('register.store'); }); Route::middleware('auth:earn')->group(function (): void { Route::post('/logout', [EarnAuthController::class, 'logout'])->name('logout'); Route::get('/verify-email', [EarnVerificationController::class, 'notice'])->name('verification.notice'); Route::post('/email/verification-notification', [EarnVerificationController::class, 'send'])->middleware('throttle:6,1')->name('verification.send'); Route::get('/verify-email/{id}/{hash}', [EarnVerificationController::class, 'verify'])->middleware(['signed', 'throttle:6,1'])->name('verification.verify'); Route::middleware(['earn.active', 'earn.verified'])->group(function (): void { Route::get('/dashboard', EarnDashboardController::class)->name('dashboard'); Route::get('/api-keys', [EarnApiKeyController::class, 'index'])->name('api-keys.index'); Route::post('/api-keys', [EarnApiKeyController::class, 'store'])->middleware('throttle:5,1')->name('api-keys.store'); Route::patch('/api-keys/{apiKey}/status', [EarnApiKeyController::class, 'status'])->middleware('throttle:10,1')->name('api-keys.status'); Route::post('/api-keys/{apiKey}/revoke', [EarnApiKeyController::class, 'revoke'])->middleware('throttle:10,1')->name('api-keys.revoke'); Route::delete('/api-keys/{apiKey}', [EarnApiKeyController::class, 'destroy'])->middleware('throttle:10,1')->name('api-keys.destroy'); }); }); }); Route::middleware('guest')->group(function () { Route::get('/login', [AuthenticatedSessionController::class, 'create'])->name('login'); Route::post('/login', [AuthenticatedSessionController::class, 'store'])->middleware('throttle:10,1'); Route::get('/register', [RegisteredUserController::class, 'create'])->name('register'); Route::post('/register', [RegisteredUserController::class, 'store'])->middleware('throttle:6,1'); Route::get('/forgot-password', [PasswordResetLinkController::class, 'create'])->name('password.request'); Route::post('/forgot-password', [PasswordResetLinkController::class, 'store'])->middleware('throttle:3,1')->name('password.email'); Route::get('/reset-password/{token}', [NewPasswordController::class, 'create'])->name('password.reset'); Route::post('/reset-password', [NewPasswordController::class, 'store'])->middleware('throttle:6,1')->name('password.store'); }); Route::middleware(['auth', 'active'])->group(function () { Route::delete('/admin/users/{user}', UserDeletionController::class) ->middleware(['verified', 'admin.portal']) ->name('admin.users.destroy'); Route::post('/logout', [AuthenticatedSessionController::class, 'destroy'])->name('logout'); Route::middleware('customer.portal')->group(function () { Route::get('/profile', [ProfileController::class, 'show'])->name('profile.show'); Route::put('/profile', [ProfileController::class, 'update'])->middleware('throttle:20,1')->name('profile.update'); Route::put('/profile/email', [ProfileController::class, 'email'])->middleware('throttle:5,1')->name('profile.email'); Route::put('/profile/password', [ProfileController::class, 'password'])->middleware('throttle:5,1')->name('profile.password'); Route::post('/profile/email/verification-notification', [ProfileController::class, 'resend'])->middleware('throttle:3,1')->name('profile.verification.send'); Route::post('/profile/sessions/logout-others', [ProfileController::class, 'logoutOthers'])->middleware('throttle:5,1')->name('profile.sessions.logout-others'); Route::get('/settings', [SettingsController::class, 'show'])->name('settings.show'); Route::put('/settings/appearance', [SettingsController::class, 'appearance'])->name('settings.appearance'); Route::put('/settings/regional', [SettingsController::class, 'regional'])->name('settings.regional'); Route::put('/settings/dashboard', [SettingsController::class, 'dashboard'])->name('settings.dashboard'); Route::put('/settings/notifications', [SettingsController::class, 'notifications'])->name('settings.notifications'); Route::post('/settings/reset', [SettingsController::class, 'reset'])->middleware('throttle:5,1')->name('settings.reset'); Route::get('/verify-email', [EmailVerificationController::class, 'notice'])->name('verification.notice'); Route::get('/verify-email/{id}/{hash}', [EmailVerificationController::class, 'verify'])->middleware(['signed', 'throttle:6,1'])->name('verification.verify'); Route::post('/email/verification-notification', [EmailVerificationController::class, 'send'])->middleware('throttle:6,1')->name('verification.send'); Route::get('/dashboard', DashboardController::class)->middleware('verified')->name('dashboard'); Route::middleware('verified')->group(function () { Route::get('/projects', [ProjectController::class, 'index'])->name('projects.index'); Route::get('/projects/create', [ProjectController::class, 'create'])->name('projects.create'); Route::post('/projects', [ProjectController::class, 'store'])->name('projects.store'); Route::get('/projects/{customerProject}', [ProjectController::class, 'show'])->name('projects.show'); Route::get('/projects/{customerProject}/edit', [ProjectController::class, 'edit'])->name('projects.edit'); Route::match(['put', 'patch'], '/projects/{customerProject}', [ProjectController::class, 'update'])->name('projects.update'); Route::post('/projects/{customerProject}/archive', [ProjectController::class, 'archive'])->name('projects.archive'); Route::post('/projects/{customerProject}/restore', [ProjectController::class, 'restore'])->name('projects.restore'); Route::get('/keywords', [KeywordController::class, 'index'])->name('keywords.index'); Route::get('/keywords/create', [KeywordController::class, 'create'])->name('keywords.create'); Route::post('/keywords', [KeywordController::class, 'store'])->name('keywords.store'); Route::get('/keywords/{keyword}', [KeywordController::class, 'show'])->name('keywords.show'); Route::get('/keywords/{keyword}/edit', [KeywordController::class, 'edit'])->name('keywords.edit'); Route::match(['put', 'patch'], '/keywords/{keyword}', [KeywordController::class, 'update'])->name('keywords.update'); Route::patch('/keywords/{keyword}/status', [KeywordController::class, 'status'])->name('keywords.status'); Route::post('/keywords/{keyword}/archive', [KeywordController::class, 'archive'])->name('keywords.archive'); Route::post('/keywords/{keyword}/restore', [KeywordController::class, 'restore'])->name('keywords.restore'); Route::get('/rankings', [RankingHistoryController::class, 'index'])->name('rankings.index'); Route::get('/rankings/keywords/{keyword}', [RankingHistoryController::class, 'keyword'])->name('rankings.keywords.show'); Route::get('/rankings/checks/{serpCheck}', [RankingHistoryController::class, 'check'])->name('rankings.checks.show'); Route::get('/serp-checks', [SerpCheckController::class, 'customerIndex'])->name('serp-checks.index'); Route::get('/serp-checks/{serpCheck}', [SerpCheckController::class, 'customerShow'])->name('serp-checks.show'); Route::post('/keywords/{keyword}/serp-checks', [SerpCheckController::class, 'customerStore'])->middleware('throttle:serp-manual')->name('serp-checks.store'); Route::get('/reports/visibility', VisibilityReportController::class)->name('reports.visibility'); Route::get('/reports/winners', WinnersReportController::class)->name('reports.winners'); Route::get('/reports/losers', LosersReportController::class)->name('reports.losers'); Route::get('/reports/competitors', [CompetitorController::class, 'index'])->name('reports.competitors'); Route::post('/projects/{p}/competitors', [CompetitorController::class, 'store'])->name('competitors.store'); Route::put('/projects/{p}/competitors/{c}', [CompetitorController::class, 'update'])->name('competitors.update'); Route::post('/projects/{p}/competitors/{c}/archive', [CompetitorController::class, 'archive'])->name('competitors.archive'); Route::post('/projects/{p}/competitors/{c}/restore', [CompetitorController::class, 'restore'])->name('competitors.restore'); Route::get('/projects/{p}/competitors/{c}', [CompetitorController::class, 'show'])->name('competitors.show'); Route::get('/projects/{customerProject}/keywords', [KeywordController::class, 'index'])->name('projects.keywords.index'); Route::get('/projects/{customerProject}/keywords/create', [KeywordController::class, 'create'])->name('projects.keywords.create'); Route::post('/projects/{customerProject}/keywords', [KeywordController::class, 'store'])->name('projects.keywords.store'); Route::get('/projects/{customerProject}/keywords/{customerKeyword}', [KeywordController::class, 'legacyShow'])->name('projects.keywords.show'); Route::get('/projects/{customerProject}/keywords/{customerKeyword}/edit', [KeywordController::class, 'legacyEdit'])->name('projects.keywords.edit'); Route::match(['put', 'patch'], '/projects/{customerProject}/keywords/{customerKeyword}', [KeywordController::class, 'legacyUpdate'])->name('projects.keywords.update'); Route::post('/projects/{customerProject}/keywords/{customerKeyword}/archive', [KeywordController::class, 'legacyArchive'])->name('projects.keywords.archive'); Route::post('/projects/{customerProject}/keywords/{customerKeyword}/restore', [KeywordController::class, 'legacyRestore'])->name('projects.keywords.restore'); Route::get('/projects/{customerProject}/keywords/{customerKeyword}/serp-checks', [SerpCheckController::class, 'index'])->name('projects.keywords.serp-checks.index'); Route::post('/projects/{customerProject}/keywords/{customerKeyword}/serp-checks', [SerpCheckController::class, 'store'])->middleware('throttle:serp-manual')->name('projects.keywords.serp-checks.store'); Route::get('/projects/{customerProject}/keywords/{customerKeyword}/serp-checks/{customerSerpCheck}', [SerpCheckController::class, 'show'])->name('projects.keywords.serp-checks.show'); Route::patch('/projects/{customerProject}/keywords/{customerKeyword}/tracking', [SerpCheckController::class, 'tracking'])->name('projects.keywords.tracking'); }); }); });