diff --git a/app/Http/Controllers/LicenseController.php b/app/Http/Controllers/LicenseController.php index 1c1e0c1cb99e..b9221a82c719 100644 --- a/app/Http/Controllers/LicenseController.php +++ b/app/Http/Controllers/LicenseController.php @@ -89,6 +89,10 @@ class LicenseController extends BaseController $license_key = request()->input('license_key'); $product_id = 3; + if(substr($license_key, 0, 3) == 'v5_') { + return $this->v5ClaimLicense($license_key, $product_id); + } + $url = config('ninja.license_url')."/claim_license?license_key={$license_key}&product_id={$product_id}&get_date=true"; $data = trim(CurlUtils::get($url)); @@ -149,15 +153,15 @@ class LicenseController extends BaseController return response()->json($error, 400); } - public function v5ClaimLicense(Request $request) + public function v5ClaimLicense(string $license_key) { $this->checkLicense(); /* Catch claim license requests */ - if (config('ninja.environment') == 'selfhost' && request()->has('license_key')) { + if (config('ninja.environment') == 'selfhost') { // $response = Http::get( "http://ninja.test:8000/claim_license", [ $response = Http::get("https://invoicing.co/claim_license", [ - 'license_key' => $request->input('license_key'), + 'license_key' => $license_key, 'product_id' => 3, ]); diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php index 130ef2b2bb6f..c7fcc7b5ce6e 100644 --- a/app/Http/Kernel.php +++ b/app/Http/Kernel.php @@ -11,54 +11,55 @@ namespace App\Http; -use App\Http\Middleware\ApiSecretCheck; +use App\Utils\Ninja; +use App\Http\Middleware\Cors; +use App\Http\Middleware\SetDb; +use App\Http\Middleware\Locale; +use App\Http\Middleware\SetWebDb; +use App\Http\Middleware\UrlSetDb; +use App\Http\Middleware\TokenAuth; +use App\Http\Middleware\SetEmailDb; +use App\Http\Middleware\VerifyHash; +use App\Http\Middleware\SetInviteDb; +use App\Http\Middleware\TrimStrings; use App\Http\Middleware\Authenticate; -use App\Http\Middleware\CheckClientExistence; -use App\Http\Middleware\CheckForMaintenanceMode; -use App\Http\Middleware\ClientPortalEnabled; +use App\Http\Middleware\ContactSetDb; +use App\Http\Middleware\QueryLogging; +use App\Http\Middleware\TrustProxies; +use App\Http\Middleware\UserVerified; +use App\Http\Middleware\VendorLocale; +use App\Http\Middleware\PhantomSecret; +use App\Http\Middleware\SetDocumentDb; +use App\Http\Middleware\ApiSecretCheck; use App\Http\Middleware\ContactAccount; +use App\Http\Middleware\EncryptCookies; +use App\Http\Middleware\SessionDomains; use App\Http\Middleware\ContactKeyLogin; use App\Http\Middleware\ContactRegister; -use App\Http\Middleware\ContactSetDb; -use App\Http\Middleware\ContactTokenAuth; -use App\Http\Middleware\Cors; -use App\Http\Middleware\EncryptCookies; -use App\Http\Middleware\Locale; -use App\Http\Middleware\PasswordProtection; -use App\Http\Middleware\PhantomSecret; -use App\Http\Middleware\QueryLogging; -use App\Http\Middleware\RedirectIfAuthenticated; -use App\Http\Middleware\SessionDomains; -use App\Http\Middleware\SetDb; -use App\Http\Middleware\SetDbByCompanyKey; -use App\Http\Middleware\SetDocumentDb; use App\Http\Middleware\SetDomainNameDb; -use App\Http\Middleware\SetEmailDb; -use App\Http\Middleware\SetInviteDb; -use App\Http\Middleware\SetWebDb; -use App\Http\Middleware\Shop\ShopTokenAuth; -use App\Http\Middleware\TokenAuth; -use App\Http\Middleware\TrimStrings; -use App\Http\Middleware\TrustProxies; -use App\Http\Middleware\UrlSetDb; -use App\Http\Middleware\UserVerified; -use App\Http\Middleware\VendorContactKeyLogin; -use App\Http\Middleware\VendorLocale; use App\Http\Middleware\VerifyCsrfToken; -use App\Http\Middleware\VerifyHash; -use Illuminate\Auth\Middleware\AuthenticateWithBasicAuth; +use App\Http\Middleware\ContactTokenAuth; use Illuminate\Auth\Middleware\Authorize; -use Illuminate\Auth\Middleware\EnsureEmailIsVerified; -use Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse; -use Illuminate\Foundation\Http\Kernel as HttpKernel; -use Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull; -use Illuminate\Foundation\Http\Middleware\ValidatePostSize; +use App\Http\Middleware\SetDbByCompanyKey; +use App\Http\Middleware\PasswordProtection; +use App\Http\Middleware\ClientPortalEnabled; +use App\Http\Middleware\CheckClientExistence; +use App\Http\Middleware\VendorContactKeyLogin; use Illuminate\Http\Middleware\SetCacheHeaders; -use Illuminate\Routing\Middleware\SubstituteBindings; -use Illuminate\Routing\Middleware\ThrottleRequests; -use Illuminate\Routing\Middleware\ValidateSignature; use Illuminate\Session\Middleware\StartSession; +use App\Http\Middleware\CheckForMaintenanceMode; +use App\Http\Middleware\RedirectIfAuthenticated; +use Illuminate\Routing\Middleware\ThrottleRequests; +use Illuminate\Foundation\Http\Kernel as HttpKernel; +use Illuminate\Routing\Middleware\ValidateSignature; +use Illuminate\Auth\Middleware\EnsureEmailIsVerified; +use Illuminate\Routing\Middleware\SubstituteBindings; use Illuminate\View\Middleware\ShareErrorsFromSession; +use Illuminate\Auth\Middleware\AuthenticateWithBasicAuth; +use Illuminate\Foundation\Http\Middleware\ValidatePostSize; +use Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse; +use Illuminate\Routing\Middleware\ThrottleRequestsWithRedis; +use Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull; class Kernel extends HttpKernel { @@ -75,9 +76,7 @@ class Kernel extends HttpKernel TrimStrings::class, ConvertEmptyStringsToNull::class, TrustProxies::class, - // \Illuminate\Http\Middleware\HandleCors::class, Cors::class, - ]; /** @@ -140,7 +139,6 @@ class Kernel extends HttpKernel 'cors' => Cors::class, 'guest' => RedirectIfAuthenticated::class, 'signed' => ValidateSignature::class, - 'throttle' => ThrottleRequests::class, 'verified' => EnsureEmailIsVerified::class, 'query_logging' => QueryLogging::class, 'token_auth' => TokenAuth::class, @@ -152,7 +150,6 @@ class Kernel extends HttpKernel 'email_db' => SetEmailDb::class, 'invite_db' => SetInviteDb::class, 'password_protected' => PasswordProtection::class, - 'signed' => ValidateSignature::class, 'portal_enabled' => ClientPortalEnabled::class, 'url_db' => UrlSetDb::class, 'web_db' => SetWebDb::class, @@ -162,7 +159,6 @@ class Kernel extends HttpKernel 'vendor_locale' => VendorLocale::class, 'contact_register' => ContactRegister::class, 'verify_hash' => VerifyHash::class, - 'shop_token_auth' => ShopTokenAuth::class, 'phantom_secret' => PhantomSecret::class, 'contact_key_login' => ContactKeyLogin::class, 'vendor_contact_key_login' => VendorContactKeyLogin::class, @@ -170,6 +166,7 @@ class Kernel extends HttpKernel 'user_verified' => UserVerified::class, 'document_db' => SetDocumentDb::class, 'session_domain' => SessionDomains::class, + //we dyanamically add the throttle middleware in RouteServiceProvider ]; protected $middlewarePriority = [ @@ -189,7 +186,6 @@ class Kernel extends HttpKernel ContactTokenAuth::class, ContactKeyLogin::class, Authenticate::class, - ShopTokenAuth::class, ContactRegister::class, PhantomSecret::class, CheckClientExistence::class, @@ -199,4 +195,5 @@ class Kernel extends HttpKernel SubstituteBindings::class, ContactAccount::class, ]; + } diff --git a/app/Providers/RouteServiceProvider.php b/app/Providers/RouteServiceProvider.php index 86a681d00160..adc66e8fe479 100644 --- a/app/Providers/RouteServiceProvider.php +++ b/app/Providers/RouteServiceProvider.php @@ -11,14 +11,17 @@ namespace App\Providers; -use App\Models\Scheduler; use App\Utils\Ninja; +use App\Models\Scheduler; +use Illuminate\Http\Request; use App\Utils\Traits\MakesHash; +use Illuminate\Support\Facades\Route; use Illuminate\Cache\RateLimiting\Limit; +use Illuminate\Support\Facades\RateLimiter; +use Illuminate\Routing\Middleware\ThrottleRequests; +use Illuminate\Routing\Middleware\ThrottleRequestsWithRedis; use Illuminate\Database\Eloquent\ModelNotFoundException as ModelNotFoundException; use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider; -use Illuminate\Support\Facades\RateLimiter; -use Illuminate\Support\Facades\Route; class RouteServiceProvider extends ServiceProvider { @@ -32,6 +35,15 @@ class RouteServiceProvider extends ServiceProvider public function boot() { parent::boot(); + + + if (Ninja::isHosted()) { + app('router')->aliasMiddleware('throttle', ThrottleRequestsWithRedis::class); + // app('router')->aliasMiddleware('throttle', ThrottleRequests::class); + + } else { + app('router')->aliasMiddleware('throttle', ThrottleRequests::class); + } Route::bind('task_scheduler', function ($value) { if (is_numeric($value)) { @@ -44,29 +56,30 @@ class RouteServiceProvider extends ServiceProvider ->where('id', $this->decodePrimaryKey($value))->firstOrFail(); }); - RateLimiter::for('login', function () { + RateLimiter::for('login', function (Request $request) { if (Ninja::isSelfHost()) { return Limit::none(); } else { - return Limit::perMinute(50); + return Limit::perMinute(50)->by($request->ip()); } }); - RateLimiter::for('api', function () { + RateLimiter::for('api', function (Request $request) { if (Ninja::isSelfHost()) { return Limit::none(); } else { - return Limit::perMinute(300); + return Limit::perMinute(300)->by($request->ip()); } }); - RateLimiter::for('refresh', function () { + RateLimiter::for('refresh', function (Request $request) { if (Ninja::isSelfHost()) { return Limit::none(); } else { - return Limit::perMinute(200); + return Limit::perMinute(200)->by($request->ip()); } }); + } /** diff --git a/app/Services/Subscription/SubscriptionService.php b/app/Services/Subscription/SubscriptionService.php index d011bdba4867..5c2437403203 100644 --- a/app/Services/Subscription/SubscriptionService.php +++ b/app/Services/Subscription/SubscriptionService.php @@ -167,7 +167,7 @@ class SubscriptionService { //send license to the user. $invoice = $payment_hash->fee_invoice; - $license_key = Str::uuid()->toString(); + $license_key = "v5_".Str::uuid()->toString(); $invoice->footer = ctrans('texts.white_label_body', ['license_key' => $license_key]); $recurring_invoice = $this->convertInvoiceToRecurring($payment_hash->payment->client_id); diff --git a/config/cache.php b/config/cache.php index d35901c5bbc9..dc2f8766b2f0 100644 --- a/config/cache.php +++ b/config/cache.php @@ -17,6 +17,7 @@ return [ 'default' => env('CACHE_DRIVER', 'file'), + 'limiter' => 'redis', /* |-------------------------------------------------------------------------- | Cache Stores @@ -30,7 +31,6 @@ return [ | "memcached", "redis", "dynamodb", "octane", "null" | */ - 'stores' => [ 'apc' => [ diff --git a/lang/en/texts.php b/lang/en/texts.php index aad041a416b3..054f2c91fea4 100644 --- a/lang/en/texts.php +++ b/lang/en/texts.php @@ -1191,7 +1191,7 @@ $LANG = array( 'plan_started' => 'Plan Started', 'plan_expires' => 'Plan Expires', - 'white_label_button' => 'White Label', + 'white_label_button' => 'Purchase White Label', 'pro_plan_year_description' => 'One year enrollment in the Invoice Ninja Pro Plan.', 'pro_plan_month_description' => 'One month enrollment in the Invoice Ninja Pro Plan.', diff --git a/routes/api.php b/routes/api.php index aa90773fe12e..01136609845e 100644 --- a/routes/api.php +++ b/routes/api.php @@ -136,7 +136,6 @@ Route::group(['middleware' => ['throttle:api', 'api_db', 'token_auth', 'locale'] Route::post('charts/chart_summary', [ChartController::class, 'chart_summary'])->name('chart.chart_summary'); Route::post('claim_license', [LicenseController::class, 'index'])->name('license.index'); - Route::post('v5_claim_license', [LicenseController::class, 'v5ClaimLicense'])->name('license.v5_claim_license'); Route::resource('clients', ClientController::class); // name = (clients. index / create / show / update / destroy / edit Route::put('clients/{client}/upload', [ClientController::class, 'upload'])->name('clients.upload');