Skip to content

Commit

Permalink
Merge pull request #1461 from adrum/feature/renew-certs
Browse files Browse the repository at this point in the history
added the ability to renew certs and view their expiration dates
  • Loading branch information
mattstauffer authored Dec 21, 2023
2 parents 34b4f03 + 42f4f39 commit 81a2b3b
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 7 deletions.
35 changes: 35 additions & 0 deletions cli/Valet/Site.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Valet;

use DateTime;
use DomainException;
use Illuminate\Support\Collection;
use PhpFpm;
Expand Down Expand Up @@ -435,6 +436,26 @@ public function secured(): array
})->unique()->values()->all();
}

/**
* Get all of the URLs with expiration dates that are currently secured.
*/
public function securedWithDates(): array
{
return collect($this->secured())->map(function ($site) {

$filePath = $this->certificatesPath() . '/' . $site . '.crt';

$expiration = $this->cli->run("openssl x509 -enddate -noout -in $filePath");

$expiration = str_replace('notAfter=', '', $expiration);

return [
'site' => $site,
'exp' => new DateTime($expiration),
];
})->unique()->values()->all();
}

public function isSecured(string $site): bool
{
$tld = $this->config->read()['tld'];
Expand Down Expand Up @@ -480,6 +501,20 @@ public function secure(string $url, ?string $siteConf = null, int $certificateEx
$this->files->putAsUser($this->nginxPath($url), $siteConf);
}

/**
* Renews all domains with a trusted TLS certificate.
*/
public function renew($expireIn): void
{
collect($this->securedWithDates())->each(function ($row) use ($expireIn) {
$url = $this->domain($row['site']);

$this->secure($url, null, $expireIn);

info('The [' . $url . '] site has been secured with a fresh TLS certificate.');
});
}

/**
* If CA and root certificates are nonexistent, create them and trust the root cert.
*
Expand Down
33 changes: 27 additions & 6 deletions cli/app.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ function (ConsoleCommandEvent $event) {
output();
DnsMasq::install(Configuration::read()['tld']);
output();
Site::renew();
Nginx::restart();
output();
Valet::symlinkToUsersBin();
Expand Down Expand Up @@ -278,13 +279,33 @@ function (ConsoleCommandEvent $event) {
/**
* Display all of the currently secured sites.
*/
$app->command('secured', function (OutputInterface $output) {
$sites = collect(Site::secured())->map(function ($url) {
return ['Site' => $url];
});
$app->command('secured [--expiring] [--days=]', function (OutputInterface $output, $expiring = null, $days = 60) {
$now = (new Datetime())->add(new DateInterval('P' . $days . 'D'));
$sites = collect(Site::securedWithDates())
->when($expiring, fn ($collection) => $collection->filter(fn ($row) => $row['exp'] < $now))
->map(function ($row) {
return [
'Site' => $row['site'],
'Valid Until' => $row['exp']->format('Y-m-d H:i:s T'),
];
})
->when($expiring, fn ($collection) => $collection->sortBy('Valid Until'));

return table(['Site', 'Valid Until'], $sites->all());
})->descriptions('Display all of the currently secured sites', [
'--expiring' => 'Limits the results to only sites expiring within the next 60 days.',
'--days' => 'To be used with --expiring. Limits the results to only sites expiring within the next X days. Default is set to 60.',
]);

table(['Site'], $sites->all());
})->descriptions('Display all of the currently secured sites');
/**
* Renews all domains with a trusted TLS certificate.
*/
$app->command('renew [--expireIn=]', function (OutputInterface $output, $expireIn = 368) {
Site::renew($expireIn);
Nginx::restart();
})->descriptions('Renews all domains with a trusted TLS certificate.', [
'--expireIn' => 'The amount of days the self signed certificate is valid for. Default is set to "368"',
]);

/**
* Create an Nginx proxy config for the specified domain.
Expand Down
23 changes: 22 additions & 1 deletion tests/CliTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -436,7 +436,12 @@ public function test_secured_command()
[$app, $tester] = $this->appAndTester();

$site = Mockery::mock(RealSite::class);
$site->shouldReceive('secured')->andReturn(['tighten.test']);
$site->shouldReceive('securedWithDates')->andReturn([
[
'site' => 'tighten.test',
'exp' => new DateTime('Aug 2 13:16:40 2024 GMT')
]
]);
swap(RealSite::class, $site);

$tester->run(['command' => 'secured']);
Expand All @@ -445,6 +450,22 @@ public function test_secured_command()
$this->assertStringContainsString('tighten.test', $tester->getDisplay());
}

public function test_renew_command()
{
[$app, $tester] = $this->appAndTester();

$site = Mockery::mock(RealSite::class);
$site->shouldReceive('renew')->andReturn();
swap(RealSite::class, $site);

$nginx = Mockery::mock(Nginx::class);
$nginx->shouldReceive('restart')->once();
swap(Nginx::class, $nginx);

$tester->run(['command' => 'renew']);
$tester->assertCommandIsSuccessful();
}

public function test_proxy_command()
{
[$app, $tester] = $this->appAndTester();
Expand Down

0 comments on commit 81a2b3b

Please sign in to comment.