Cut over-engineering found by a repo-wide audit
- Config: auth, services, logging, queue and database only repeated the
framework's own files and are gone; the others keep only the keys that
differ (app version, cache serializable_classes, session cookie name,
Markdown mail theme, the shares disk, three Octane values, Livewire's
pagination theme and payload guards).
- Email verification is removed: User never implemented MustVerifyEmail,
so it was never enforced, and SealShare has a single admin and no
registration. CreateNewUser goes with it.
- FileEncryptionService::encryptFile() and generateSalt() were only used
by tests; tests build files with encryptTestFile() in tests/Pest.php.
- The expiration options are defined once, as Share::EXPIRATIONS. "30 Days"
now lasts 30 days instead of a calendar month, and Admin settings only
save a default expiration that is one of the options.
- One-caller helpers are inlined, the uploader reads chunk responses with
XHR's responseType, and starter-kit leftovers are removed.
- Docker: PHP reads the PHP_* limits from the environment itself
(${VAR:-default} in uploads.ini); both entrypoints stop writing the ini.
docker-compose.yml shares the app and scheduler variables through one
anchor. The dev image installs gd for the screenshot publisher and fake
test images.
- Development runs in Docker only: the composer dev script, concurrently,
laravel/pail, laravel/sail, autoprefixer and the shell-quote override
are gone.
- phpunit.xml forces the test environment with <server> entries, so tests
run in the dev container no longer use its real database.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
a62edbcefb
commit
4530298398
@@ -45,7 +45,7 @@ test('encrypt and decrypt round-trip works', function () {
|
||||
|
||||
$key = $this->service->generateRandomKey();
|
||||
|
||||
$this->service->encryptFile($sourcePath, $encryptedPath, $key, 1024);
|
||||
encryptTestFile($sourcePath, $encryptedPath, $key, 1024);
|
||||
|
||||
expect(file_get_contents($encryptedPath))->not->toContain($content);
|
||||
expect(decryptToString($this->service, $encryptedPath, $key))->toBe($content);
|
||||
@@ -57,14 +57,14 @@ test('decrypt with wrong key fails', function () {
|
||||
|
||||
file_put_contents($sourcePath, 'Secret data');
|
||||
|
||||
$this->service->encryptFile($sourcePath, $encryptedPath, $this->service->generateRandomKey(), 1024);
|
||||
encryptTestFile($sourcePath, $encryptedPath, $this->service->generateRandomKey(), 1024);
|
||||
|
||||
decryptToString($this->service, $encryptedPath, $this->service->generateRandomKey());
|
||||
})->throws(RuntimeException::class, 'Decryption failed');
|
||||
|
||||
test('derive key produces consistent results', function () {
|
||||
$password = 'my-secure-password';
|
||||
$salt = $this->service->generateSalt();
|
||||
$salt = bin2hex(random_bytes(32));
|
||||
|
||||
$key1 = $this->service->deriveKey($password, $salt);
|
||||
$key2 = $this->service->deriveKey($password, $salt);
|
||||
@@ -73,7 +73,7 @@ test('derive key produces consistent results', function () {
|
||||
});
|
||||
|
||||
test('derive key with different passwords produces different keys', function () {
|
||||
$salt = $this->service->generateSalt();
|
||||
$salt = bin2hex(random_bytes(32));
|
||||
|
||||
$key1 = $this->service->deriveKey('password1', $salt);
|
||||
$key2 = $this->service->deriveKey('password2', $salt);
|
||||
@@ -84,8 +84,8 @@ test('derive key with different passwords produces different keys', function ()
|
||||
test('derive key with different salts produces different keys', function () {
|
||||
$password = 'same-password';
|
||||
|
||||
$key1 = $this->service->deriveKey($password, $this->service->generateSalt());
|
||||
$key2 = $this->service->deriveKey($password, $this->service->generateSalt());
|
||||
$key1 = $this->service->deriveKey($password, bin2hex(random_bytes(32)));
|
||||
$key2 = $this->service->deriveKey($password, bin2hex(random_bytes(32)));
|
||||
|
||||
expect($key1)->not->toBe($key2);
|
||||
});
|
||||
@@ -97,13 +97,6 @@ test('generate random key returns 64 char hex string', function () {
|
||||
expect(ctype_xdigit($key))->toBeTrue();
|
||||
});
|
||||
|
||||
test('generate salt returns 64 char hex string', function () {
|
||||
$salt = $this->service->generateSalt();
|
||||
|
||||
expect(strlen($salt))->toBe(64);
|
||||
expect(ctype_xdigit($salt))->toBeTrue();
|
||||
});
|
||||
|
||||
test('password-derived key encrypt/decrypt round-trip works', function () {
|
||||
$sourcePath = $this->tempDir.'/source.txt';
|
||||
$encryptedPath = $this->tempDir.'/encrypted.enc';
|
||||
@@ -111,9 +104,9 @@ test('password-derived key encrypt/decrypt round-trip works', function () {
|
||||
|
||||
file_put_contents($sourcePath, $content);
|
||||
|
||||
$key = bin2hex($this->service->deriveKey('user-password', $this->service->generateSalt()));
|
||||
$key = bin2hex($this->service->deriveKey('user-password', bin2hex(random_bytes(32))));
|
||||
|
||||
$this->service->encryptFile($sourcePath, $encryptedPath, $key, 1024);
|
||||
encryptTestFile($sourcePath, $encryptedPath, $key, 1024);
|
||||
|
||||
expect(decryptToString($this->service, $encryptedPath, $key))->toBe($content);
|
||||
});
|
||||
@@ -124,7 +117,7 @@ test('an encrypted file starts with the SEALCHK2 header and its chunk size', fun
|
||||
|
||||
file_put_contents($sourcePath, 'test content');
|
||||
|
||||
$this->service->encryptFile($sourcePath, $encryptedPath, $this->service->generateRandomKey(), 1024);
|
||||
encryptTestFile($sourcePath, $encryptedPath, $this->service->generateRandomKey(), 1024);
|
||||
|
||||
expect(file_get_contents($encryptedPath, false, null, 0, 12))->toBe('SEALCHK2'.pack('N', 1024));
|
||||
});
|
||||
@@ -137,7 +130,7 @@ test('multi-chunk round-trip works', function () {
|
||||
file_put_contents($sourcePath, $content);
|
||||
|
||||
$key = $this->service->generateRandomKey();
|
||||
$this->service->encryptFile($sourcePath, $encryptedPath, $key, 1000);
|
||||
encryptTestFile($sourcePath, $encryptedPath, $key, 1000);
|
||||
|
||||
expect(filesize($encryptedPath))->toBe(19 + 3 * 16 + 2500);
|
||||
expect(decryptToString($this->service, $encryptedPath, $key))->toBe($content);
|
||||
@@ -151,7 +144,7 @@ test('exact chunk boundary round-trip works', function () {
|
||||
file_put_contents($sourcePath, $content);
|
||||
|
||||
$key = $this->service->generateRandomKey();
|
||||
$this->service->encryptFile($sourcePath, $encryptedPath, $key, 1000);
|
||||
encryptTestFile($sourcePath, $encryptedPath, $key, 1000);
|
||||
|
||||
expect(filesize($encryptedPath))->toBe(19 + 2 * 16 + 2000);
|
||||
expect(decryptToString($this->service, $encryptedPath, $key))->toBe($content);
|
||||
@@ -164,7 +157,7 @@ test('empty file round-trip works', function () {
|
||||
file_put_contents($sourcePath, '');
|
||||
|
||||
$key = $this->service->generateRandomKey();
|
||||
$this->service->encryptFile($sourcePath, $encryptedPath, $key, 1000);
|
||||
encryptTestFile($sourcePath, $encryptedPath, $key, 1000);
|
||||
|
||||
expect(filesize($encryptedPath))->toBe(19 + 16);
|
||||
expect(decryptToString($this->service, $encryptedPath, $key))->toBe('');
|
||||
@@ -197,7 +190,7 @@ test('a file cut short at a chunk boundary fails to decrypt', function () {
|
||||
file_put_contents($sourcePath, random_bytes(3000));
|
||||
|
||||
$key = $this->service->generateRandomKey();
|
||||
$this->service->encryptFile($sourcePath, $encryptedPath, $key, 1000);
|
||||
encryptTestFile($sourcePath, $encryptedPath, $key, 1000);
|
||||
|
||||
$handle = fopen($encryptedPath, 'r+b');
|
||||
ftruncate($handle, 19 + 2 * (1000 + 16));
|
||||
@@ -265,7 +258,7 @@ test('wrong key on chunked file throws exception', function () {
|
||||
|
||||
file_put_contents($sourcePath, random_bytes(2500));
|
||||
|
||||
$this->service->encryptFile($sourcePath, $encryptedPath, $this->service->generateRandomKey(), 1000);
|
||||
encryptTestFile($sourcePath, $encryptedPath, $this->service->generateRandomKey(), 1000);
|
||||
|
||||
decryptToString($this->service, $encryptedPath, $this->service->generateRandomKey());
|
||||
})->throws(RuntimeException::class, 'Decryption failed');
|
||||
|
||||
Reference in New Issue
Block a user