diff --git a/README.md b/README.md index 249494c..6953293 100644 --- a/README.md +++ b/README.md @@ -25,35 +25,21 @@ You can install the package via composer: composer require castelnuovo/laravel-age ``` -You can publish the config file with: - -```bash -php artisan vendor:publish --tag="laravel-age-config" -``` - -This is the contents of the published config file: - -```php -return [ - 'identity' => env('AGE_IDENTITY') -]; -``` - ## Usage ```php -use Castelnuovo\LaravelAge\LaravelAge; +use Castelnuovo\LaravelAge\Age; $message = 'Hello World!'; -$age = LaravelAge::generateKeypair(); +$age = Age::generateKeypair(); $privateKey = $age->getPrivateKey(); $publicKey = $age->getPublicKey(); -$age2 = new LaravelAge(publicKey: $publicKey); +$age2 = new Age(publicKey: $publicKey); $encrypted_message = $age2->encrypt($message); -$age3 = new LaravelAge(privateKey: $privateKey); +$age3 = new Age(privateKey: $privateKey); $decrypted_message = $age3->decrypt($encrypted_message); echo $message === $decrypted_message ? 'Success' : 'Failed'; diff --git a/composer.json b/composer.json index 96f779f..e618675 100644 --- a/composer.json +++ b/composer.json @@ -74,10 +74,7 @@ "laravel": { "providers": [ "Castelnuovo\\LaravelAge\\LaravelAgeServiceProvider" - ], - "aliases": { - "LaravelAge": "Castelnuovo\\LaravelAge\\Facades\\LaravelAge" - } + ] } }, "minimum-stability": "dev", diff --git a/config/age.php b/config/age.php deleted file mode 100644 index ff59240..0000000 --- a/config/age.php +++ /dev/null @@ -1,5 +0,0 @@ - env('AGE_IDENTITY'), -]; diff --git a/phpstan.neon.dist b/phpstan.neon.dist index f4a34f0..1ed9871 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -5,7 +5,6 @@ parameters: level: 9 paths: - src - - config tmpDir: build/phpstan checkOctaneCompatibility: true checkModelProperties: true diff --git a/src/LaravelAge.php b/src/Age.php similarity index 85% rename from src/LaravelAge.php rename to src/Age.php index a68f4f7..5e18595 100755 --- a/src/LaravelAge.php +++ b/src/Age.php @@ -4,14 +4,13 @@ use Exception; -class LaravelAge +class Age { public function __construct(private ?PrivateKey $privateKey = null, private ?PublicKey $publicKey = null) { /* If no keys are provided, use the one from .env or create a pair. */ if (! isset($privateKey) && ! isset($publicKey)) { - /** @phpstan-ignore-next-line */ - $this->privateKey = new PrivateKey(config('laravel-age.identity')); + $this->privateKey = PrivateKey::generate(); $this->publicKey = $this->privateKey->getPublicKey(); } @@ -21,11 +20,11 @@ public function __construct(private ?PrivateKey $privateKey = null, private ?Pub } } - public static function generateKeypair(): LaravelAge + public static function generateKeypair(): Age { - $privateKey = new PrivateKey(); + $privateKey = PrivateKey::generate(); - return new LaravelAge($privateKey, $privateKey->getPublicKey()); + return new Age($privateKey, $privateKey->getPublicKey()); } public function getPublicKey(): PublicKey diff --git a/src/Facades/LaravelAge.php b/src/Facades/LaravelAge.php deleted file mode 100644 index b9a2953..0000000 --- a/src/Facades/LaravelAge.php +++ /dev/null @@ -1,16 +0,0 @@ -name('laravel-age') - ->hasConfigFile(); + ->name('laravel-age'); } } diff --git a/src/PrivateKey.php b/src/PrivateKey.php index 7c86d7f..d00ba6b 100644 --- a/src/PrivateKey.php +++ b/src/PrivateKey.php @@ -13,21 +13,8 @@ class PrivateKey { private string $privateKey; - public function __construct(string $privateKey = '') + public function __construct(string $privateKey) { - if (! $privateKey) { - $result = Process::pipe([ - 'age-keygen', - 'grep -E "^AGE-SECRET-KEY-[A-Za-z0-9]{59}$"', - ]); - - if ($result->failed()) { - throw new Exception('Failed to generate private key!'); - } - - $privateKey = $result->output(); - } - $privateKey = str($privateKey)->trim(); if (! $privateKey->startsWith('AGE-SECRET-KEY-') || $privateKey->length() !== 74) { @@ -37,6 +24,20 @@ public function __construct(string $privateKey = '') $this->privateKey = $privateKey; } + public static function generate(): self + { + $result = Process::pipe([ + 'age-keygen', + 'grep -E "^AGE-SECRET-KEY-[A-Za-z0-9]{59}$"', + ]); + + if ($result->failed()) { + throw new Exception('Failed to generate private key!'); + } + + return new self($result->output()); + } + public function encode(): string { return $this->privateKey; @@ -62,7 +63,11 @@ public function decrypt(string $message, bool $base64): string $ulid = Str::ulid(); $dir = TemporaryDirectory::make()->deleteWhenDestroyed(); - $data = $base64 ? base64_decode(str_replace(['-', '_'], ['+', '/'], $message)) : $message; + $data = $base64 ? base64_decode($message, strict: true) : $message; + if (! $data) { + throw new Exception('Invalid message provided!'); + } + Storage::build(['driver' => 'local', 'root' => $dir->path()])->put($ulid, $data); /** diff --git a/tests/LaravelAgeTest.php b/tests/LaravelAgeTest.php index eb33a26..e271cc3 100644 --- a/tests/LaravelAgeTest.php +++ b/tests/LaravelAgeTest.php @@ -1,15 +1,15 @@ encode())->toBeString(); + expect(PrivateKey::generate()->encode())->toBeString(); }); it('can generate public key', function () { - $publicKey = (new PrivateKey())->getPublicKey(); + $publicKey = PrivateKey::generate()->getPublicKey(); expect($publicKey->encode())->toBeString(); }); @@ -37,9 +37,9 @@ })->throws(Exception::class); it('can generate keypair', function () { - $age = LaravelAge::generateKeypair(); + $age = Age::generateKeypair(); - expect($age)->toBeInstanceOf(LaravelAge::class); + expect($age)->toBeInstanceOf(Age::class); expect($age->getPrivateKey())->toBeInstanceOf(PrivateKey::class); expect($age->getPublicKey())->toBeInstanceOf(PublicKey::class); }); @@ -47,7 +47,7 @@ it('can encrypt with an provided private key', function () { $encodeKey = 'AGE-SECRET-KEY-1TKGRTQP4H79MTNHVDRSA3L0CS7MFSMW0DQX80CWP0JDUFL97RRJSPK9777'; $privateKey = new PrivateKey($encodeKey); - $age = new LaravelAge(privateKey: $privateKey); + $age = new Age(privateKey: $privateKey); expect($age->encrypt('message'))->toBeString(); }); @@ -55,7 +55,7 @@ it('can encrypt with an provided public key', function () { $encodeKey = 'age1xqrfpqxz55ersvu6mmhwzcctqk27ppnatms7p9zruclrm8tt4y0q3apxuc'; $publicKey = new PublicKey($encodeKey); - $age = new LaravelAge(publicKey: $publicKey); + $age = new Age(publicKey: $publicKey); expect($age->encrypt('message'))->toBeString(); }); @@ -63,7 +63,7 @@ it('can decrypt with an provided private key (using base64)', function () { $encodeKey = 'AGE-SECRET-KEY-1TKGRTQP4H79MTNHVDRSA3L0CS7MFSMW0DQX80CWP0JDUFL97RRJSPK9777'; $privateKey = new PrivateKey($encodeKey); - $age = new LaravelAge(privateKey: $privateKey); + $age = new Age(privateKey: $privateKey); $message = 'Hello, World!'; $encrypted = $age->encrypt($message); @@ -75,7 +75,7 @@ it('can decrypt with an provided private key (without using base64)', function () { $encodeKey = 'AGE-SECRET-KEY-1TKGRTQP4H79MTNHVDRSA3L0CS7MFSMW0DQX80CWP0JDUFL97RRJSPK9777'; $privateKey = new PrivateKey($encodeKey); - $age = new LaravelAge(privateKey: $privateKey); + $age = new Age(privateKey: $privateKey); $message = 'Hello, World!'; $encrypted = $age->encrypt($message, false); @@ -87,7 +87,7 @@ it('cannot decrypt with an provided public key', function () { $encodeKey = 'age1xqrfpqxz55ersvu6mmhwzcctqk27ppnatms7p9zruclrm8tt4y0q3apxuc'; $publicKey = new PublicKey($encodeKey); - $age = new LaravelAge(publicKey: $publicKey); + $age = new Age(publicKey: $publicKey); $message = 'Hello, World!'; $encrypted = $age->encrypt($message); @@ -97,7 +97,7 @@ it('cannot decrypt with an provided private key (using base64 only to encrypt)', function () { $encodeKey = 'age1xqrfpqxz55ersvu6mmhwzcctqk27ppnatms7p9zruclrm8tt4y0q3apxuc'; $publicKey = new PublicKey($encodeKey); - $age = new LaravelAge(publicKey: $publicKey); + $age = new Age(publicKey: $publicKey); $message = 'Hello, World!'; $encrypted = $age->encrypt($message); @@ -107,7 +107,7 @@ it('cannot decrypt with an provided private key (using base64 only to decrypt)', function () { $encodeKey = 'age1xqrfpqxz55ersvu6mmhwzcctqk27ppnatms7p9zruclrm8tt4y0q3apxuc'; $publicKey = new PublicKey($encodeKey); - $age = new LaravelAge(publicKey: $publicKey); + $age = new Age(publicKey: $publicKey); $message = 'Hello, World!'; $encrypted = $age->encrypt($message, false); @@ -117,14 +117,14 @@ it('runs usage code from readme', function () { $message = 'Hello World!'; - $age = LaravelAge::generateKeypair(); + $age = Age::generateKeypair(); $privateKey = $age->getPrivateKey(); $publicKey = $age->getPublicKey(); - $age2 = new LaravelAge(publicKey: $publicKey); + $age2 = new Age(publicKey: $publicKey); $encrypted_message = $age2->encrypt($message); - $age3 = new LaravelAge(privateKey: $privateKey); + $age3 = new Age(privateKey: $privateKey); $decrypted_message = $age3->decrypt($encrypted_message); expect($message)->toBe($decrypted_message);