Deploy Ladill Merchant / deploy (push) Successful in 29s
Customers can connect their own domain to a merchant page (storefront/event): add a domain, point an A record (apex + www) to the app server, click Verify — DNS is checked, then Ladill Domains' central SSL service issues + installs the Let's Encrypt cert and calls back to flip it live. The custom domain then serves the mapped page (host resolution on /). Feature-gated: only active when a Domains SSL API key is set, so this deploy is inert until wired. - custom_domains table + CustomDomain model - CustomDomainService (DNS verify, request cert), DomainsSslClient, DnsResolver - settings UI panel, signed SSL callback receiver, host resolution on / - feature tests (DNS verify/fail, signed callback, ownership) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
44 lines
1.4 KiB
PHP
44 lines
1.4 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Api;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use App\Services\CustomDomain\CustomDomainService;
|
|
use Illuminate\Http\JsonResponse;
|
|
use Illuminate\Http\Request;
|
|
|
|
/**
|
|
* Signed completion callback from Ladill Domains' SSL service. Flips a custom
|
|
* domain to live (or failed) once the certificate is issued. Auth is the HMAC
|
|
* signature over the raw body (shared SSL_CALLBACK_SECRET), not a session.
|
|
*/
|
|
class SslCallbackController extends Controller
|
|
{
|
|
public function __invoke(Request $request, CustomDomainService $service): JsonResponse
|
|
{
|
|
$secret = (string) config('customdomain.callback_secret');
|
|
$body = $request->getContent();
|
|
$signature = (string) $request->header('X-Ladill-Signature', '');
|
|
|
|
if ($secret === '' || ! hash_equals(hash_hmac('sha256', $body, $secret), $signature)) {
|
|
return response()->json(['error' => 'Invalid signature.'], 401);
|
|
}
|
|
|
|
$payload = json_decode($body, true);
|
|
$data = (array) ($payload['data'] ?? []);
|
|
$host = (string) ($data['host'] ?? '');
|
|
if ($host === '') {
|
|
return response()->json(['error' => 'Missing host.'], 422);
|
|
}
|
|
|
|
$service->applyCallback(
|
|
$host,
|
|
(string) ($data['status'] ?? 'failed'),
|
|
$data['expires_at'] ?? null,
|
|
$data['last_error'] ?? null,
|
|
);
|
|
|
|
return response()->json(['status' => 'ok']);
|
|
}
|
|
}
|