- Kontaktformular: keine Mail mehr an die eingegebene Adresse (wurde als Spam-Versender missbraucht); Anfrage nur an Kontakt-Adresse + Berater (BCC), Reply-To = Absender; Eingaben in der Mail escaped - Kontakt + Registrierung: Cloudflare Turnstile statt reCAPTCHA (Schluessel aus dem Code in die .env), Rate-Limits, Honeypot + Mindest-Ausfuellzeit, Namensregel (lateinische Schrift, max. 50 Zeichen), Form Requests - Registrierung: Partner-Nummer nur fuer aktive Berater (vorher ungeprueft) - CRM: POST /register abgeschaltet (legte ohne Captcha Benutzer an) - Passwort-Mindestlaenge systemweit 8 Zeichen ueber Password::defaults() - Log abgefangener Anfragen: storage/logs/form-spam-*.log - Doku und Protokoll: dev/2026-10-09-spam/README.md Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
187 lines
7.8 KiB
PHP
187 lines
7.8 KiB
PHP
<?php
|
|
|
|
use App\Domain\EarlyDomainParser;
|
|
use App\Models\IqImage;
|
|
use App\Models\ProductImage;
|
|
use App\Models\UserShop;
|
|
use App\Models\UserShopOnSite;
|
|
use App\Services\LocaleGuard;
|
|
|
|
/*
|
|
|--------------------------------------------------------------------------
|
|
| Geteilte Routen (Shared Routes)
|
|
|--------------------------------------------------------------------------
|
|
|
|
|
| Diese Routen sind auf allen Domains verfügbar, die die 'web' Middleware-Gruppe
|
|
| verwenden. Sie werden vom RouteServiceProvider geladen.
|
|
|
|
|
*/
|
|
|
|
// Rechtliche und Kontakt-Routen - Umleitung zur Shop-Domain für checkout.*
|
|
// Verwendet EarlyDomainParser für domain-awareness
|
|
if (EarlyDomainParser::getCurrentDomainType() === 'checkout') {
|
|
// Shop-Domain aus Config laden
|
|
$shopHost = config('domains.domains.shop.host');
|
|
$protocol = config('domains.protocol', 'https://');
|
|
$shopBaseUrl = $protocol.$shopHost;
|
|
|
|
// Für Checkout-Domain: Umleitung zur Shop-Domain
|
|
Route::get('/datenschutz', function () use ($shopBaseUrl) {
|
|
return redirect()->away($shopBaseUrl.'/datenschutz');
|
|
})->name('legal.data-protected');
|
|
|
|
Route::get('/impressum', function () use ($shopBaseUrl) {
|
|
return redirect()->away($shopBaseUrl.'/impressum');
|
|
})->name('legal.imprint');
|
|
|
|
Route::get('/agb', function () use ($shopBaseUrl) {
|
|
return redirect()->away($shopBaseUrl.'/agb');
|
|
})->name('legal.agb');
|
|
|
|
Route::get('/kontakt', function () use ($shopBaseUrl) {
|
|
return redirect()->away($shopBaseUrl.'/kontakt');
|
|
})->name('contact.create');
|
|
|
|
Route::get('/zahlungsarten', function () use ($shopBaseUrl) {
|
|
return redirect()->away($shopBaseUrl.'/zahlungsarten');
|
|
})->name('zahlungsarten');
|
|
|
|
Route::get('/versandkosten', function () use ($shopBaseUrl) {
|
|
return redirect()->away($shopBaseUrl.'/versandkosten');
|
|
})->name('versandkosten');
|
|
} else {
|
|
// Für alle anderen Domains: normale Controller-Routen
|
|
Route::get('/datenschutz', 'HomeController@legalDataProtected')->name('legal.data-protected');
|
|
Route::get('/impressum', 'HomeController@legalImprint')->name('legal.imprint');
|
|
Route::get('/agb', 'HomeController@legalAGB')->name('legal.agb');
|
|
Route::get('/kontakt', 'Web\ContactController@create')->name('contact.create');
|
|
Route::post('/kontakt', 'Web\ContactController@store')->middleware('throttle:contact-form')->name('contact.store');
|
|
Route::get('/zahlungsarten', 'HomeController@zahlungsarten')->name('zahlungsarten');
|
|
Route::get('/versandkosten', 'HomeController@versandkosten')->name('versandkosten');
|
|
}
|
|
|
|
// File storage route für alle Domains (Rechnungen, Downloads, etc.)
|
|
// Auth-Prüfung erfolgt im FileController selbst je nach Kontext
|
|
// Optional: locale Parameter für mehrsprachige PDFs (z.B. /storage/file/123/invoice/download/es)
|
|
Route::get('/storage/file/{id}/{from}/{do?}/{locale?}', 'FileController@show')->name('storage_file');
|
|
|
|
// Sprachwechsler
|
|
Route::post('/change_website_lang', 'Web\SiteController@changeLang')->name('language.change');
|
|
|
|
// Route für den Sprachwechsel (aus alter utility.php wiederhergestellt)
|
|
Route::get('translation/{locale}', function ($locale) {
|
|
$normalized = LocaleGuard::normalize($locale);
|
|
if ($normalized === null) {
|
|
return redirect()->back();
|
|
}
|
|
|
|
app()->setLocale($normalized);
|
|
session()->put('locale', $normalized);
|
|
|
|
// Optional: Sprache für eingeloggte Benutzer speichern
|
|
if (auth()->guard('user')->check()) {
|
|
auth()->guard('user')->user()->update(['lang' => $normalized]);
|
|
}
|
|
if (auth()->guard('customers')->check()) {
|
|
auth()->guard('customers')->user()->update(['language' => $normalized]);
|
|
}
|
|
|
|
return redirect()->back();
|
|
})->name('translation');
|
|
|
|
// Bild-Routen (aus alter utility.php wiederhergestellt)
|
|
Route::get('/product/image/{slug}', function ($slug = null) {
|
|
if ($image = ProductImage::where('slug', 'like', $slug)->first()) {
|
|
$path = storage_path('app/public').'/images/product'.'/'.$image->product_id.'/'.$image->filename;
|
|
if (file_exists($path)) {
|
|
return response()->file($path);
|
|
}
|
|
}
|
|
abort(404);
|
|
})->name('product_image');
|
|
|
|
Route::get('storage/images/{from}/{slug}', function ($from = null, $slug = null) {
|
|
if ($from == 'shop') {
|
|
if ($image = UserShop::where('filename', $slug)->first()) {
|
|
$path = storage_path('app/public').'/images/shop'.'/'.$image->filename;
|
|
if (file_exists($path)) {
|
|
return Response::file($path);
|
|
}
|
|
}
|
|
}
|
|
})->name('storage_images');
|
|
|
|
Route::get('/iq/image/{slug}', function ($slug = null) {
|
|
if ($image = IqImage::where('slug', $slug)->first()) {
|
|
$path = storage_path('app/public').'/images/iq_images/'.$image->filename;
|
|
if (file_exists($path)) {
|
|
return Response::file($path);
|
|
}
|
|
}
|
|
})->name('iq_image');
|
|
|
|
Route::get('/user_shop/image/{slug}', function ($slug = null) {
|
|
if ($image = UserShopOnSite::where('slug', $slug)->first()) {
|
|
$path = storage_path('app/public').'/images/user_shop'.'/'.$image->user_shop_id.'/'.$image->filename;
|
|
if (file_exists($path)) {
|
|
return Response::file($path);
|
|
}
|
|
}
|
|
})->name('user_shop_image');
|
|
|
|
Route::get('/shop/product/image/{slug}', function ($slug = null) {
|
|
if ($image = ProductImage::where('slug', $slug)->first()) {
|
|
$path = storage_path('app/public').'/images/product'.'/'.$image->product_id.'/'.$image->filename;
|
|
if (file_exists($path)) {
|
|
return Response::file($path);
|
|
}
|
|
}
|
|
})->name('shop_product_image');
|
|
|
|
// Alias für /home, damit auch /home erreichbar ist
|
|
|
|
// Checkout-Weiterleitung nur für Domains, die NICHT checkout.* sind
|
|
if (EarlyDomainParser::getCurrentDomainType() !== 'checkout') {
|
|
// Checkout-Domain aus Config laden
|
|
$checkoutHost = config('domains.domains.checkout.host');
|
|
$protocol = config('domains.protocol', 'https://');
|
|
$checkoutBaseUrl = $protocol.$checkoutHost;
|
|
|
|
Route::get('/checkout/card/{identifier?}', function ($identifier = null) use ($checkoutBaseUrl) {
|
|
$path = '/checkout/card/'.($identifier ?: '');
|
|
|
|
return redirect()->away($checkoutBaseUrl.$path);
|
|
})->name('checkout.checkout_card');
|
|
|
|
Route::post('/checkout/card/final', function () use ($checkoutBaseUrl) {
|
|
return redirect()->away($checkoutBaseUrl.'/checkout/card/final');
|
|
})->name('checkout.checkout_card_final');
|
|
|
|
// Weiterleitung für Transaktionsstatus
|
|
Route::get('/transaction/status/{status?}/{reference?}', function ($status = null, $reference = null) use ($checkoutBaseUrl) {
|
|
$path = '/transaction/status/'.($status ?: '').'/'.($reference ?: '');
|
|
|
|
return redirect()->away($checkoutBaseUrl.$path);
|
|
})->name('checkout.transaction_status');
|
|
|
|
Route::post('/transaction/status/{status?}/{reference?}', function ($status = null, $reference = null) use ($checkoutBaseUrl) {
|
|
$path = '/transaction/status/'.($status ?: '').'/'.($reference ?: '');
|
|
|
|
return redirect()->away($checkoutBaseUrl.$path);
|
|
})->name('checkout.transaction_status_post');
|
|
|
|
Route::get('/transaction/approved/{transactionId}/{reference}', function ($transactionId, $reference) use ($checkoutBaseUrl) {
|
|
return redirect()->away($checkoutBaseUrl."/transaction/approved/{$transactionId}/{$reference}");
|
|
})->name('checkout.transaction_approved');
|
|
}
|
|
|
|
Route::get('/register/verify/{confirmationCode}', 'HomeController@verify')->name('register_verify');
|
|
|
|
// Gesetzliche Online-Widerrufsfunktion (Widerrufs-Button-Pflicht ab 19.06.2026)
|
|
Route::get('/widerruf', 'Web\WithdrawalController@create')->name('withdrawal.create');
|
|
Route::post('/widerruf/pruefen', 'Web\WithdrawalController@lookup')
|
|
->middleware('throttle:20,1')
|
|
->name('withdrawal.lookup');
|
|
Route::post('/widerruf/absenden', 'Web\WithdrawalController@store')
|
|
->middleware('throttle:10,1')
|
|
->name('withdrawal.store');
|