refactor(encryption): drop client-side encryption setup endpoint
Transactions now live unencrypted in the backend; new data is never encrypted client-side again. Remove the /api/encryption/setup endpoint, its form request, and the dead encrypted=false transaction filter. The decrypt-migration path (encryption/message, encrypted=true) stays.
This commit is contained in:
parent
b76a0de074
commit
418f38fe92
|
|
@ -21,8 +21,6 @@ class TransactionController extends Controller
|
|||
|
||||
if ($request->query('encrypted') === 'true') {
|
||||
$query->where(fn ($q) => $q->whereNotNull('description_iv')->orWhereNotNull('notes_iv'));
|
||||
} elseif ($request->query('encrypted') === 'false') {
|
||||
$query->whereNull('description_iv')->whereNull('notes_iv');
|
||||
}
|
||||
|
||||
$transactions = $query->simplePaginate(100);
|
||||
|
|
|
|||
|
|
@ -2,34 +2,11 @@
|
|||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Http\Requests\SetupEncryptionRequest;
|
||||
use App\Models\EncryptedMessage;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class EncryptionController extends Controller
|
||||
{
|
||||
public function setup(SetupEncryptionRequest $request): JsonResponse
|
||||
{
|
||||
$user = $request->user();
|
||||
|
||||
$user->update([
|
||||
'encryption_salt' => $request->validated('salt'),
|
||||
]);
|
||||
|
||||
EncryptedMessage::query()->updateOrCreate(
|
||||
['user_id' => $user->id],
|
||||
[
|
||||
'encrypted_content' => $request->validated('encrypted_content'),
|
||||
'iv' => $request->validated('iv'),
|
||||
]
|
||||
);
|
||||
|
||||
return response()->json([
|
||||
'message' => 'Encryption setup completed successfully',
|
||||
]);
|
||||
}
|
||||
|
||||
public function getMessage(Request $request): JsonResponse
|
||||
{
|
||||
$user = $request->user();
|
||||
|
|
|
|||
|
|
@ -1,31 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Contracts\Validation\ValidationRule;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
|
||||
class SetupEncryptionRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*/
|
||||
public function authorize(): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array<string, ValidationRule|array<mixed>|string>
|
||||
*/
|
||||
public function rules(): array
|
||||
{
|
||||
return [
|
||||
'salt' => ['required', 'string', 'size:24'],
|
||||
'encrypted_content' => ['required', 'string'],
|
||||
'iv' => ['required', 'string', 'size:16'],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
@ -14,8 +14,7 @@ use App\Http\Controllers\Sync\TransactionSyncController;
|
|||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
Route::middleware(['web', 'auth'])->group(function () {
|
||||
// Encryption
|
||||
Route::post('encryption/setup', [EncryptionController::class, 'setup']);
|
||||
// Encryption (legacy decrypt-migration support only)
|
||||
Route::get('encryption/message', [EncryptionController::class, 'getMessage']);
|
||||
|
||||
// Import Data (for import drawers)
|
||||
|
|
|
|||
|
|
@ -27,23 +27,6 @@ test('encrypted transactions endpoint returns only encrypted transactions', func
|
|||
expect($data[0]['id'])->toBe($encrypted->id);
|
||||
});
|
||||
|
||||
test('plaintext filter returns only plaintext transactions', function () {
|
||||
Transaction::factory()->create([
|
||||
'user_id' => $this->user->id,
|
||||
'description_iv' => 'some-iv',
|
||||
]);
|
||||
$plaintext = Transaction::factory()->plaintext()->create([
|
||||
'user_id' => $this->user->id,
|
||||
]);
|
||||
|
||||
$response = $this->getJson('/api/transactions?encrypted=false');
|
||||
|
||||
$response->assertOk();
|
||||
$data = $response->json('data');
|
||||
expect($data)->toHaveCount(1);
|
||||
expect($data[0]['id'])->toBe($plaintext->id);
|
||||
});
|
||||
|
||||
test('encrypted transactions endpoint paginates correctly', function () {
|
||||
$account = Account::factory()->create(['user_id' => $this->user->id]);
|
||||
$category = Category::factory()->create(['user_id' => $this->user->id]);
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ use App\Models\EncryptedMessage;
|
|||
use App\Models\User;
|
||||
|
||||
use function Pest\Laravel\actingAs;
|
||||
use function Pest\Laravel\assertDatabaseHas;
|
||||
|
||||
test('authenticated user without encryption salt can access setup page', function () {
|
||||
$user = User::factory()->create(['encryption_salt' => null]);
|
||||
|
|
@ -14,54 +13,6 @@ test('authenticated user without encryption salt can access setup page', functio
|
|||
$response->assertSuccessful();
|
||||
});
|
||||
|
||||
test('user can setup encryption', function () {
|
||||
$user = User::factory()->create(['encryption_salt' => null]);
|
||||
|
||||
$response = actingAs($user)->postJson('/api/encryption/setup', [
|
||||
'salt' => str_repeat('a', 24),
|
||||
'encrypted_content' => 'encrypted_test_content',
|
||||
'iv' => str_repeat('b', 16),
|
||||
]);
|
||||
|
||||
$response->assertSuccessful();
|
||||
|
||||
$user->refresh();
|
||||
|
||||
expect($user->encryption_salt)->toBe(str_repeat('a', 24));
|
||||
|
||||
assertDatabaseHas('encrypted_messages', [
|
||||
'user_id' => $user->id,
|
||||
'encrypted_content' => 'encrypted_test_content',
|
||||
'iv' => str_repeat('b', 16),
|
||||
]);
|
||||
});
|
||||
|
||||
test('encryption setup requires valid salt', function () {
|
||||
$user = User::factory()->create(['encryption_salt' => null]);
|
||||
|
||||
$response = actingAs($user)->postJson('/api/encryption/setup', [
|
||||
'salt' => 'invalid',
|
||||
'encrypted_content' => 'encrypted_test_content',
|
||||
'iv' => str_repeat('b', 16),
|
||||
]);
|
||||
|
||||
$response->assertUnprocessable();
|
||||
$response->assertJsonValidationErrors(['salt']);
|
||||
});
|
||||
|
||||
test('encryption setup requires valid iv', function () {
|
||||
$user = User::factory()->create(['encryption_salt' => null]);
|
||||
|
||||
$response = actingAs($user)->postJson('/api/encryption/setup', [
|
||||
'salt' => str_repeat('a', 24),
|
||||
'encrypted_content' => 'encrypted_test_content',
|
||||
'iv' => 'invalid',
|
||||
]);
|
||||
|
||||
$response->assertUnprocessable();
|
||||
$response->assertJsonValidationErrors(['iv']);
|
||||
});
|
||||
|
||||
test('user can retrieve encrypted message', function () {
|
||||
$user = User::factory()->create([
|
||||
'encryption_salt' => str_repeat('a', 24),
|
||||
|
|
|
|||
Loading…
Reference in New Issue