Skip to content

Commit

Permalink
Merge pull request #8 from castelnuovo/v2
Browse files Browse the repository at this point in the history
V2
  • Loading branch information
lucacastelnuovo authored May 26, 2024
2 parents 070dbd5 + f1805ae commit 020c7d5
Show file tree
Hide file tree
Showing 9 changed files with 46 additions and 82 deletions.
22 changes: 4 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down
5 changes: 1 addition & 4 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,7 @@
"laravel": {
"providers": [
"Castelnuovo\\LaravelAge\\LaravelAgeServiceProvider"
],
"aliases": {
"LaravelAge": "Castelnuovo\\LaravelAge\\Facades\\LaravelAge"
}
]
}
},
"minimum-stability": "dev",
Expand Down
5 changes: 0 additions & 5 deletions config/age.php

This file was deleted.

1 change: 0 additions & 1 deletion phpstan.neon.dist
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ parameters:
level: 9
paths:
- src
- config
tmpDir: build/phpstan
checkOctaneCompatibility: true
checkModelProperties: true
11 changes: 5 additions & 6 deletions src/LaravelAge.php → src/Age.php
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}

Expand All @@ -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
Expand Down
16 changes: 0 additions & 16 deletions src/Facades/LaravelAge.php

This file was deleted.

3 changes: 1 addition & 2 deletions src/LaravelAgeServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ public function configurePackage(Package $package): void
* More info: https://github.com/spatie/laravel-package-tools
*/
$package
->name('laravel-age')
->hasConfigFile();
->name('laravel-age');
}
}
35 changes: 20 additions & 15 deletions src/PrivateKey.php
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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;
Expand All @@ -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);

/**
Expand Down
30 changes: 15 additions & 15 deletions tests/LaravelAgeTest.php
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
<?php

use Castelnuovo\LaravelAge\LaravelAge;
use Castelnuovo\LaravelAge\Age;
use Castelnuovo\LaravelAge\PrivateKey;
use Castelnuovo\LaravelAge\PublicKey;

it('can generate private key', function () {
expect((new PrivateKey())->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();
});
Expand Down Expand Up @@ -37,33 +37,33 @@
})->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);
});

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();
});

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();
});

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);
Expand All @@ -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);
Expand All @@ -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);
Expand All @@ -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);
Expand All @@ -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);
Expand All @@ -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);
Expand Down

0 comments on commit 020c7d5

Please sign in to comment.