Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F117710130
D3896.1774885465.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Authored By
Unknown
Size
8 KB
Referenced Files
None
Subscribers
None
D3896.1774885465.diff
View Options
diff --git a/src/app/Http/Controllers/API/SignupController.php b/src/app/Http/Controllers/API/SignupController.php
--- a/src/app/Http/Controllers/API/SignupController.php
+++ b/src/app/Http/Controllers/API/SignupController.php
@@ -151,10 +151,11 @@
* Validation of the verification code.
*
* @param \Illuminate\Http\Request $request HTTP request
+ * @param bool $update Update the signup code record
*
* @return \Illuminate\Http\JsonResponse JSON response
*/
- public function verify(Request $request)
+ public function verify(Request $request, $update = true)
{
// Validate the request args
$v = Validator::make(
@@ -182,9 +183,14 @@
}
// For signup last-step mode remember the code object, so we can delete it
- // with single SQL query (->delete()) instead of two (::destroy())
+ // with single SQL query (->delete()) instead of two
$request->code = $code;
+ if ($update) {
+ $code->verify_ip_address = $request->ip();
+ $code->save();
+ }
+
$has_domain = $this->getPlan()->hasDomain();
// Return user name and email/phone/voucher from the codes database,
@@ -255,7 +261,7 @@
];
} else {
// Validate verification codes (again)
- $v = $this->verify($request);
+ $v = $this->verify($request, false);
if ($v->status() !== 200) {
return $v;
}
@@ -338,9 +344,13 @@
$invitation->save();
}
- // Remove the verification code
+ // Soft-delete the verification code, and store some more info with it
if ($request->code) {
- $request->code->delete();
+ $request->code->user_id = $user->id;
+ $request->code->submit_ip_address = $request->ip();
+ $request->code->deleted_at = \now();
+ $request->code->timestamps = false;
+ $request->code->save();
}
DB::commit();
diff --git a/src/app/SignupCode.php b/src/app/SignupCode.php
--- a/src/app/SignupCode.php
+++ b/src/app/SignupCode.php
@@ -2,6 +2,7 @@
namespace App;
+use App\Traits\BelongsToUserTrait;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
@@ -22,11 +23,14 @@
* @property ?string $plan Plan title
* @property string $short_code Short validation code
* @property \Carbon\Carbon $updated_at The update timestamp
+ * @property string $submit_ip_address IP address the final signup submit request came from
+ * @property string $verify_ip_address IP address the code verify request came from
* @property ?string $voucher Voucher discount code
*/
class SignupCode extends Model
{
use SoftDeletes;
+ use BelongsToUserTrait;
public const SHORTCODE_LENGTH = 5;
public const CODE_LENGTH = 32;
@@ -58,6 +62,9 @@
/** @var array<string, string> The attributes that should be cast */
protected $casts = [
+ 'created_at' => 'datetime:Y-m-d H:i:s',
+ 'deleted_at' => 'datetime:Y-m-d H:i:s',
+ 'updated_at' => 'datetime:Y-m-d H:i:s',
'expires_at' => 'datetime:Y-m-d H:i:s',
'headers' => 'array'
];
diff --git a/src/database/migrations/2022_10_10_100000_signup_codes_user_id.php b/src/database/migrations/2022_10_10_100000_signup_codes_user_id.php
new file mode 100644
--- /dev/null
+++ b/src/database/migrations/2022_10_10_100000_signup_codes_user_id.php
@@ -0,0 +1,46 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\DB;
+use Illuminate\Support\Facades\Schema;
+
+return new class extends Migration
+{
+ /**
+ * Run the migrations.
+ *
+ * @return void
+ */
+ public function up()
+ {
+ Schema::table(
+ 'signup_codes',
+ function (Blueprint $table) {
+ $table->string('verify_ip_address')->index()->nullable();
+ $table->string('submit_ip_address')->index()->nullable();
+
+ $table->bigInteger('user_id')->index()->nullable();
+ $table->foreign('user_id')->references('id')->on('users')
+ ->onUpdate('cascade')->onDelete('cascade');
+ }
+ );
+ }
+
+ /**
+ * Reverse the migrations.
+ *
+ * @return void
+ */
+ public function down()
+ {
+ Schema::table(
+ 'signup_codes',
+ function (Blueprint $table) {
+ $table->dropColumn('user_id');
+ $table->dropColumn('verify_ip_address');
+ $table->dropColumn('submit_ip_address');
+ }
+ );
+ }
+};
diff --git a/src/tests/Feature/Controller/SignupTest.php b/src/tests/Feature/Controller/SignupTest.php
--- a/src/tests/Feature/Controller/SignupTest.php
+++ b/src/tests/Feature/Controller/SignupTest.php
@@ -280,7 +280,7 @@
'plan' => 'individual',
];
- $response = $this->post('/api/auth/signup/init', $data);
+ $response = $this->post('/api/auth/signup/init', $data, ['REMOTE_ADDR' => '10.1.1.2']);
$json = $response->json();
$response->assertStatus(200);
@@ -290,6 +290,12 @@
$this->assertSame('email', $json['mode']);
$this->assertNotEmpty($json['code']);
+ $code = SignupCode::find($json['code']);
+
+ $this->assertSame('10.1.1.2', $code->ip_address);
+ $this->assertSame(null, $code->verify_ip_address);
+ $this->assertSame(null, $code->submit_ip_address);
+
// Assert the email sending job was pushed once
Queue::assertPushed(\App\Jobs\SignupVerificationEmail::class, 1);
@@ -395,12 +401,14 @@
public function testSignupVerifyValidInput(array $result): array
{
$code = SignupCode::find($result['code']);
+ $code->ip_address = '10.1.1.2';
+ $code->save();
$data = [
'code' => $code->code,
'short_code' => $code->short_code,
];
- $response = $this->post('/api/auth/signup/verify', $data);
+ $response = $this->post('/api/auth/signup/verify', $data, ['REMOTE_ADDR' => '10.1.1.3']);
$json = $response->json();
$response->assertStatus(200);
@@ -413,6 +421,12 @@
$this->assertSame(false, $json['is_domain']);
$this->assertTrue(is_array($json['domains']) && !empty($json['domains']));
+ $code->refresh();
+
+ $this->assertSame('10.1.1.2', $code->ip_address);
+ $this->assertSame('10.1.1.3', $code->verify_ip_address);
+ $this->assertSame(null, $code->submit_ip_address);
+
return $result;
}
@@ -560,6 +574,9 @@
$domain = $this->getPublicDomain();
$identity = \strtolower('SignupLogin@') . $domain;
$code = SignupCode::find($result['code']);
+ $code->ip_address = '10.1.1.2';
+ $code->verify_ip_address = '10.1.1.3';
+ $code->save();
$data = [
'login' => 'SignupLogin',
'domain' => $domain,
@@ -570,7 +587,7 @@
'voucher' => 'TEST',
];
- $response = $this->post('/api/auth/signup', $data);
+ $response = $this->post('/api/auth/signup', $data, ['REMOTE_ADDR' => '10.1.1.4']);
$json = $response->json();
$response->assertStatus(200);
@@ -590,8 +607,7 @@
}
);
- // Check if the code has been removed
- $this->assertNull(SignupCode::where('code', $result['code'])->first());
+ $code->refresh();
// Check if the user has been created
$user = User::where('email', $identity)->first();
@@ -599,6 +615,13 @@
$this->assertNotEmpty($user);
$this->assertSame($identity, $user->email);
+ // Check if the code has been updated and soft-deleted
+ $this->assertTrue($code->trashed());
+ $this->assertSame('10.1.1.2', $code->ip_address);
+ $this->assertSame('10.1.1.3', $code->verify_ip_address);
+ $this->assertSame('10.1.1.4', $code->submit_ip_address);
+ $this->assertSame($user->id, $code->user_id);
+
// Check user settings
$this->assertSame($result['first_name'], $user->getSetting('first_name'));
$this->assertSame($result['last_name'], $user->getSetting('last_name'));
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Mar 30, 3:44 PM (6 d, 5 h ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
18815685
Default Alt Text
D3896.1774885465.diff (8 KB)
Attached To
Mode
D3896: Store more information with a signup code
Attached
Detach File
Event Timeline