Fix #117 Redeem properly the tokens to prevent reuse

This commit is contained in:
Timothée Jaussoin 2023-08-29 09:55:04 +00:00
parent 1f84042e59
commit 17300d3ae5
3 changed files with 53 additions and 5 deletions

View file

@ -28,8 +28,8 @@ use App\Http\Controllers\Controller;
use Carbon\Carbon;
use App\Account;
use App\AccountTombstone;
use App\AccountCreationToken;
use App\AccountTombstone;
use App\Alias;
use App\Http\Controllers\Account\AuthenticateController as WebAuthenticateController;
use App\Libraries\OvhSMS;
@ -139,6 +139,12 @@ class AccountController extends Controller
$account->updatePassword($request->get('password'), $request->get('algorithm'));
$token = AccountCreationToken::where('token', $request->get('account_creation_token'))->first();
$token->used = true;
$token->account_id = $account->id;
$token->save();
Log::channel('events')->info('API: AccountCreationToken redeemed', ['token' => $request->get('account_creation_token')]);
Log::channel('events')->info('API: Account created using the public endpoint', ['id' => $account->identifier]);
// Send validation by phone
@ -199,6 +205,12 @@ class AccountController extends Controller
$account->confirmation_key = generatePin();
$account->save();
$token = AccountCreationToken::where('token', $request->get('account_creation_token'))->first();
$token->used = true;
$token->account_id = $account->id;
$token->save();
Log::channel('events')->info('API: AccountCreationToken redeemed', ['token' => $request->get('account_creation_token')]);
Log::channel('events')->info('API: Account recovery by phone', ['id' => $account->identifier]);
$ovhSMS = new OvhSMS;
@ -261,10 +273,6 @@ class AccountController extends Controller
: 'nullable|email',
]);
$token = AccountCreationToken::where('token', $request->get('account_creation_token'))->first();
$token->used = true;
$token->save();
$account = new Account;
$account->username = $request->get('username');
$account->email = $request->get('email');
@ -279,6 +287,11 @@ class AccountController extends Controller
$account->updatePassword($request->get('password'), $request->get('algorithm'));
$token = AccountCreationToken::where('token', $request->get('account_creation_token'))->first();
$token->used = true;
$token->account_id = $account->id;
$token->save();
Log::channel('events')->info('API: Account created', ['id' => $account->identifier]);
// Full reload

View file

@ -19,6 +19,7 @@
namespace Tests\Feature;
use App\Account;
use App\AccountCreationRequestToken;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
@ -102,6 +103,11 @@ class ApiAccountCreationTokenTest extends TestCase
'account_creation_token' => $token->token
]);
$response->assertStatus(422);
$this->assertDatabaseHas('account_creation_tokens', [
'used' => true,
'account_id' => Account::where('username', 'username')->first()->id,
]);
}
public function testBlacklistedUsername()

View file

@ -686,6 +686,13 @@ class ApiAccountTest extends TestCase
$password->account->refresh();
// Use the token a second time
$this->json($this->method, $this->route . '/recover-by-phone', [
'phone' => $phone,
'account_creation_token' => $token->token
])
->assertStatus(422);
$this->get($this->route . '/' . $password->account->identifier . '/recover/' . $password->account->confirmation_key)
->assertStatus(200)
->assertJson([
@ -718,6 +725,11 @@ class ApiAccountTest extends TestCase
'activated' => true,
'phone' => false
]);
$this->assertDatabaseHas('account_creation_tokens', [
'used' => true,
'account_id' => $password->account->id,
]);
}
/**
@ -765,6 +777,18 @@ class ApiAccountTest extends TestCase
'activated' => false
]);
// Re-use the token
$this->withHeaders([
'User-Agent' => $userAgent,
])->json($this->method, $this->route . '/public', [
'username' => $username . 'foo',
'algorithm' => 'SHA-256',
'password' => '2',
'email' => 'john@doe.tld',
'account_creation_token' => $token->token
])
->assertStatus(422);
// Already created
$this->json($this->method, $this->route . '/public', [
'username' => $username,
@ -792,6 +816,11 @@ class ApiAccountTest extends TestCase
'domain' => config('app.sip_domain'),
'user_agent' => $userAgent
]);
$this->assertDatabaseHas('account_creation_tokens', [
'used' => true,
'account_id' => Account::where('username', $username)->first()->id,
]);
}
public function testCreatePublicPhone()