From b96927b21977076346763124820f16917ddef361 Mon Sep 17 00:00:00 2001 From: Matt Jones Date: Wed, 10 Aug 2022 16:08:51 +0100 Subject: [PATCH 1/2] Adding subjectAlternativeNames support --- README.md | 11 ++++++++++ ...ficates_subject_alternative_names.php.stub | 22 +++++++++++++++++++ src/Jobs/RequestCertificate.php | 2 +- src/Models/LetsEncryptCertificate.php | 1 + src/PendingCertificate.php | 18 +++++++++++++++ tests/Facades/LetsEncryptTest.php | 15 +++++++++++++ tests/TestCase.php | 2 ++ 7 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 database/migrations/add_lets_encrypt_certificates_subject_alternative_names.php.stub diff --git a/README.md b/README.md index 7086206..4d8fd18 100644 --- a/README.md +++ b/README.md @@ -111,6 +111,17 @@ $certificate->delete(); $certificate->forceDelete(); ``` + +## Subject Alternative Names + +It's possible to specify Subject Alternative Names as below: + +```php +LetsEncrypt::certificate('mydomain.com') + ->subjectAlternativeNames(['mydomain2.com']) + ->create(); +``` + ## Failure events If one of the jobs fails, one of the following events will be dispatched: diff --git a/database/migrations/add_lets_encrypt_certificates_subject_alternative_names.php.stub b/database/migrations/add_lets_encrypt_certificates_subject_alternative_names.php.stub new file mode 100644 index 0000000..cbb37a6 --- /dev/null +++ b/database/migrations/add_lets_encrypt_certificates_subject_alternative_names.php.stub @@ -0,0 +1,22 @@ +json('subject_alternative_names')->nullable()->after('domain'); + }); + } + + public function down() + { + Schema::table('lets_encrypt_certificates', function (Blueprint $table) { + $table->dropColumn('subject_alternative_names'); + }); + } +} diff --git a/src/Jobs/RequestCertificate.php b/src/Jobs/RequestCertificate.php index 40023fb..d8a794f 100644 --- a/src/Jobs/RequestCertificate.php +++ b/src/Jobs/RequestCertificate.php @@ -38,7 +38,7 @@ public function __construct(LetsEncryptCertificate $certificate, int $tries = nu public function handle() { - $distinguishedName = new DistinguishedName($this->certificate->domain); + $distinguishedName = new DistinguishedName($this->certificate->domain, null, null, null, null, null, null, $this->certificate->subject_alternative_names); $csr = new CertificateRequest($distinguishedName, (new KeyPairGenerator())->generateKeyPair()); $client = LetsEncrypt::createClient(); $certificateResponse = $client->requestCertificate($this->certificate->domain, $csr); diff --git a/src/Models/LetsEncryptCertificate.php b/src/Models/LetsEncryptCertificate.php index ca22d02..df7071d 100644 --- a/src/Models/LetsEncryptCertificate.php +++ b/src/Models/LetsEncryptCertificate.php @@ -42,6 +42,7 @@ class LetsEncryptCertificate extends Model protected $casts = [ 'created' => 'boolean', + 'subject_alternative_names' => 'json', ]; public function newEloquentBuilder($query): LetsEncryptCertificateBuilder diff --git a/src/PendingCertificate.php b/src/PendingCertificate.php index 5d0ad1d..572f883 100644 --- a/src/PendingCertificate.php +++ b/src/PendingCertificate.php @@ -43,6 +43,11 @@ class PendingCertificate */ protected $delay = 0; + /** + * @var array + */ + protected $subjectAlternativeNames = []; + /** * PendingCertificate constructor. * @param string $domain @@ -67,6 +72,7 @@ public function create(): LetsEncryptCertificate $certificate = LetsEncryptCertificate::create([ 'domain' => $this->domain, + 'subject_alternative_names' => $this->subjectAlternativeNames, ]); RegisterAccount::withChain(array_merge([ @@ -118,6 +124,18 @@ public function renew(): LetsEncryptCertificate return $certificate; } + + /** + * @param array $domains + * @return static + */ + public function setSubjectAlternativeNames(array $domains): self + { + $this->subjectAlternativeNames = $domains; + + return $this; + } + /** * @param int $tries * @return static diff --git a/tests/Facades/LetsEncryptTest.php b/tests/Facades/LetsEncryptTest.php index 5eecb97..e979234 100644 --- a/tests/Facades/LetsEncryptTest.php +++ b/tests/Facades/LetsEncryptTest.php @@ -75,4 +75,19 @@ public function test_can_create_pending() RequestCertificate::class, ]); } + + /** @test */ + public function test_can_create_now_with_san() + { + Bus::fake(); + + $certificate = LetsEncrypt::certificate('somedomain.com') + ->setSubjectAlternativeNames(['other.somedomain.com']) + ->create(); + + $this->assertEquals('somedomain.com', $certificate->domain); + $this->assertEquals(['other.somedomain.com'], $certificate->subject_alternative_names); + + Bus::assertDispatched(RegisterAccount::class); + } } diff --git a/tests/TestCase.php b/tests/TestCase.php index d79914c..7282ec2 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -29,6 +29,8 @@ public function getEnvironmentSetUp($app) ]); include_once __DIR__.'/../database/migrations/create_lets_encrypt_certificates_table.php.stub'; + include_once __DIR__.'/../database/migrations/add_lets_encrypt_certificates_subject_alternative_names.php.stub'; (new \CreateLetsEncryptCertificatesTable())->up(); + (new \AddLetsEncryptCertificatesSubjectAlternativeNames())->up(); } } From 884577fd293a4e176439817913e8fd1e3f7ad341 Mon Sep 17 00:00:00 2001 From: Matt Jones Date: Mon, 12 Sep 2022 15:59:27 +0100 Subject: [PATCH 2/2] Correcting documentation function name --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4d8fd18..08436bb 100644 --- a/README.md +++ b/README.md @@ -118,7 +118,7 @@ It's possible to specify Subject Alternative Names as below: ```php LetsEncrypt::certificate('mydomain.com') - ->subjectAlternativeNames(['mydomain2.com']) + ->setSubjectAlternativeNames(['mydomain2.com']) ->create(); ```