Page MenuHomePhorge

D3896.1774885465.diff
No OneTemporary

Authored By
Unknown
Size
8 KB
Referenced Files
None
Subscribers
None

D3896.1774885465.diff

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

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)

Event Timeline