Page MenuHomePhorge

No OneTemporary

Size
14 KB
Referenced Files
None
Subscribers
None
diff --git a/src/app/Http/Kernel.php b/src/app/Http/Kernel.php
index d042dfc4..69a6845b 100644
--- a/src/app/Http/Kernel.php
+++ b/src/app/Http/Kernel.php
@@ -1,88 +1,101 @@
<?php
namespace App\Http;
use Illuminate\Foundation\Http\Kernel as HttpKernel;
class Kernel extends HttpKernel
{
/**
* The application's global HTTP middleware stack.
*
* These middleware are run during every request to your application.
*
* @var array
*/
protected $middleware = [
\App\Http\Middleware\RequestLogger::class,
\App\Http\Middleware\TrustProxies::class,
\App\Http\Middleware\CheckForMaintenanceMode::class,
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
\App\Http\Middleware\TrimStrings::class,
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
\App\Http\Middleware\DevelConfig::class,
// FIXME: CORS handling added here, I didn't find a nice way
// to add this only to the API routes
// \App\Http\Middleware\Cors::class,
];
/**
* The application's route middleware groups.
*
* @var array
*/
protected $middlewareGroups = [
'web' => [
// \App\Http\Middleware\EncryptCookies::class,
// \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
// \Illuminate\Session\Middleware\StartSession::class,
// \Illuminate\Session\Middleware\AuthenticateSession::class,
// \Illuminate\View\Middleware\ShareErrorsFromSession::class,
// \App\Http\Middleware\VerifyCsrfToken::class,
// \Illuminate\Routing\Middleware\SubstituteBindings::class,
],
'api' => [
'throttle:120,1',
'bindings',
],
];
/**
* The application's route middleware.
*
* These middleware may be assigned to groups or used individually.
*
* @var array
*/
protected $routeMiddleware = [
'admin' => \App\Http\Middleware\AuthenticateAdmin::class,
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
];
/**
* The priority-sorted list of middleware.
*
* This forces non-global middleware to always be in the given order.
*
* @var array
*/
protected $middlewarePriority = [
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\AuthenticateAdmin::class,
\App\Http\Middleware\Authenticate::class,
\Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
\Illuminate\Auth\Middleware\Authorize::class,
\App\Http\Middleware\AuthenticateAdmin::class,
];
+
+ /**
+ * Handle an incoming HTTP request.
+ *
+ * @param \Illuminate\Http\Request $request HTTP Request object
+ *
+ * @return \Illuminate\Http\Response
+ */
+ public function handle($request)
+ {
+ // Overwrite the http request object
+ return parent::handle(Request::createFrom($request));
+ }
}
diff --git a/src/app/Http/Middleware/TrustProxies.php b/src/app/Http/Middleware/TrustProxies.php
index 19ef0ca8..c8fa0d98 100644
--- a/src/app/Http/Middleware/TrustProxies.php
+++ b/src/app/Http/Middleware/TrustProxies.php
@@ -1,23 +1,28 @@
<?php
namespace App\Http\Middleware;
use Illuminate\Http\Request;
use Fideloper\Proxy\TrustProxies as Middleware;
class TrustProxies extends Middleware
{
/**
* The trusted proxies for this application.
*
* @var array|string
*/
- protected $proxies = '*';
+ protected $proxies = [
+ '10.0.0.0/8',
+ '127.0.0.1/8',
+ '172.16.0.0/12',
+ '192.168.0.0/16'
+ ];
/**
* The headers that should be used to detect proxies.
*
* @var int
*/
protected $headers = Request::HEADER_X_FORWARDED_ALL;
}
diff --git a/src/app/Http/Request.php b/src/app/Http/Request.php
new file mode 100644
index 00000000..b9c2bac3
--- /dev/null
+++ b/src/app/Http/Request.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace App\Http;
+
+use Illuminate\Http\Request as LaravelRequest;
+
+class Request extends LaravelRequest
+{
+ /**
+ * Get the client IP address.
+ *
+ * @return string|null
+ */
+ public function ip()
+ {
+ if (($client_ip = $this->headers->get('X-Client-IP')) && $this->isFromTrustedProxy()) {
+ return $client_ip;
+ }
+
+ return parent::ip();
+ }
+}
diff --git a/src/app/Observers/SignupCodeObserver.php b/src/app/Observers/SignupCodeObserver.php
index 8c832697..7f987cf2 100644
--- a/src/app/Observers/SignupCodeObserver.php
+++ b/src/app/Observers/SignupCodeObserver.php
@@ -1,67 +1,76 @@
<?php
namespace App\Observers;
use App\SignupCode;
use Carbon\Carbon;
use Illuminate\Support\Str;
class SignupCodeObserver
{
/**
* Handle the "creating" event.
*
* Ensure that the code entry is created with a random code/short_code.
*
* @param \App\SignupCode $code The code being created.
*
* @return void
*/
public function creating(SignupCode $code): void
{
$code_length = SignupCode::CODE_LENGTH;
$exp_hours = env('SIGNUP_CODE_EXPIRY', SignupCode::CODE_EXP_HOURS);
if (empty($code->code)) {
$code->short_code = SignupCode::generateShortCode();
// FIXME: Replace this with something race-condition free
while (true) {
$code->code = Str::random($code_length);
if (!SignupCode::find($code->code)) {
break;
}
}
}
+ $code->headers = collect(request()->headers->all())
+ ->filter(function ($value, $key) {
+ // remove some headers we don't care about
+ return !in_array($key, ['cookie', 'referer', 'x-test-payment-provider', 'origin']);
+ })
+ ->map(function ($value) {
+ return is_array($value) && count($value) == 1 ? $value[0] : $value;
+ });
+
$code->expires_at = Carbon::now()->addHours($exp_hours);
$code->ip_address = request()->ip();
if ($code->email) {
$parts = explode('@', $code->email);
$code->local_part = $parts[0];
$code->domain_part = $parts[1];
}
}
/**
* Handle the "updating" event.
*
* @param SignupCode $code The code being updated.
*
* @return void
*/
public function updating(SignupCode $code)
{
if ($code->email) {
$parts = explode('@', $code->email);
$code->local_part = $parts[0];
$code->domain_part = $parts[1];
} else {
$code->local_part = null;
$code->domain_part = null;
}
}
}
diff --git a/src/app/SignupCode.php b/src/app/SignupCode.php
index 29e43e2a..73ecd7af 100644
--- a/src/app/SignupCode.php
+++ b/src/app/SignupCode.php
@@ -1,104 +1,106 @@
<?php
namespace App;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
/**
* The eloquent definition of a SignupCode.
*
* @property string $code The full code identifier
* @property \Carbon\Carbon $created_at The creation timestamp
* @property \Carbon\Carbon $deleted_at The deletion timestamp
* @property string $domain_part Email domain
* @property string $email Email address
* @property \Carbon\Carbon $expires_at The code expiration timestamp
* @property string $first_name Firstname
* @property string $ip_address IP address the request came from
* @property string $last_name Lastname
* @property string $local_part Email local part
* @property string $plan Plan title
* @property string $short_code Short validation code
* @property \Carbon\Carbon $updated_at The update timestamp
* @property string $voucher Voucher discount code
*/
class SignupCode extends Model
{
use SoftDeletes;
public const SHORTCODE_LENGTH = 5;
public const CODE_LENGTH = 32;
// Code expires after so many hours
public const CODE_EXP_HOURS = 24;
/**
* The primary key associated with the table.
*
* @var string
*/
protected $primaryKey = 'code';
/**
* Indicates if the IDs are auto-incrementing.
*
* @var bool
*/
public $incrementing = false;
/**
* The "type" of the auto-incrementing ID.
*
* @var string
*/
protected $keyType = 'string';
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'code',
'email',
'expires_at',
'first_name',
'last_name',
'plan',
'short_code',
'voucher'
];
+ protected $casts = ['headers' => 'array'];
+
/**
* The attributes that should be mutated to dates.
*
* @var array
*/
protected $dates = ['expires_at'];
/**
* Check if code is expired.
*
* @return bool True if code is expired, False otherwise
*/
public function isExpired()
{
// @phpstan-ignore-next-line
return $this->expires_at ? Carbon::now()->gte($this->expires_at) : false;
}
/**
* Generate a short code (for human).
*
* @return string
*/
public static function generateShortCode(): string
{
$code_length = env('SIGNUP_CODE_LENGTH', self::SHORTCODE_LENGTH);
return \App\Utils::randStr($code_length);
}
}
diff --git a/src/composer.json b/src/composer.json
index 0f495473..c5258a8a 100644
--- a/src/composer.json
+++ b/src/composer.json
@@ -1,86 +1,87 @@
{
"name": "laravel/laravel",
"type": "project",
"description": "The Laravel Framework.",
"keywords": [
"framework",
"laravel"
],
"license": "MIT",
"repositories": [
{
"type": "vcs",
"url": "https://git.kolab.org/diffusion/PNL/php-net_ldap3.git"
}
],
"require": {
"php": "^7.1.3",
"barryvdh/laravel-dompdf": "^0.8.6",
+ "doctrine/dbal": "^2.13",
"dyrynda/laravel-nullable-fields": "*",
"fideloper/proxy": "^4.0",
"kolab/net_ldap3": "dev-master",
"laravel/framework": "6.*",
"laravel/horizon": "^3",
"laravel/tinker": "^2.4",
"mollie/laravel-mollie": "^2.9",
"morrislaptop/laravel-queue-clear": "^1.2",
"silviolleite/laravelpwa": "^2.0",
"spatie/laravel-translatable": "^4.2",
"spomky-labs/otphp": "~4.0.0",
"stripe/stripe-php": "^7.29",
"swooletw/laravel-swoole": "^2.6",
"tymon/jwt-auth": "^1.0"
},
"require-dev": {
"beyondcode/laravel-dump-server": "^1.0",
"beyondcode/laravel-er-diagram-generator": "^1.3",
"code-lts/doctum": "^5.1",
"filp/whoops": "^2.0",
"fzaninotto/faker": "^1.4",
"kirschbaum-development/mail-intercept": "^0.2.4",
"laravel/dusk": "~5.11.0",
"mockery/mockery": "^1.0",
"nunomaduro/larastan": "^0.6",
"phpstan/phpstan": "^0.12",
"phpunit/phpunit": "^8"
},
"config": {
"optimize-autoloader": true,
"preferred-install": "dist",
"sort-packages": true
},
"extra": {
"laravel": {
"dont-discover": []
}
},
"autoload": {
"psr-4": {
"App\\": "app/"
},
"classmap": [
"database/seeds",
"database/factories",
"include"
]
},
"autoload-dev": {
"psr-4": {
"Tests\\": "tests/"
}
},
"minimum-stability": "dev",
"prefer-stable": true,
"scripts": {
"post-autoload-dump": [
"Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
"@php artisan package:discover --ansi"
],
"post-root-package-install": [
"@php -r \"file_exists('.env') || copy('.env.example', '.env');\""
],
"post-create-project-cmd": [
"@php artisan key:generate --ansi"
]
}
}
diff --git a/src/database/migrations/2021_04_08_150000_signup_code_headers.php b/src/database/migrations/2021_04_08_150000_signup_code_headers.php
new file mode 100644
index 00000000..037b8298
--- /dev/null
+++ b/src/database/migrations/2021_04_08_150000_signup_code_headers.php
@@ -0,0 +1,40 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\DB;
+use Illuminate\Support\Facades\Schema;
+
+// phpcs:ignore
+class SignupCodeHeaders extends Migration
+{
+ /**
+ * Run the migrations.
+ *
+ * @return void
+ */
+ public function up()
+ {
+ Schema::table(
+ 'signup_codes',
+ function (Blueprint $table) {
+ $table->text('headers')->nullable();
+ }
+ );
+ }
+
+ /**
+ * Reverse the migrations.
+ *
+ * @return void
+ */
+ public function down()
+ {
+ Schema::table(
+ 'signup_codes',
+ function (Blueprint $table) {
+ $table->dropColumn('headers');
+ }
+ );
+ }
+}

File Metadata

Mime Type
text/x-diff
Expires
Tue, Feb 3, 4:44 AM (1 d, 11 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
427070
Default Alt Text
(14 KB)

Event Timeline