ssl->configured(); } /** Attach a custom domain to a storefront (pending DNS). */ public function attach(QrCode $storefront, string $host, bool $includeWww = true): CustomDomain { return CustomDomain::create([ 'qr_code_id' => $storefront->id, 'user_id' => $storefront->user_id, 'host' => $host, 'include_www' => $includeWww, 'status' => CustomDomain::STATUS_PENDING, 'ssl_status' => CustomDomain::STATUS_PENDING, ]); } /** * Verify the domain's A record resolves to our app server, then ask Domains * to issue the certificate. Returns [ok, message]. * * @return array{0:bool,1:string} */ public function verifyAndProvision(CustomDomain $domain): array { $serverIp = (string) config('customdomain.server_ip'); $ips = $this->dns->aRecords($domain->host); if (! in_array($serverIp, $ips, true)) { $domain->forceFill([ 'last_error' => 'DNS not pointing to '.$serverIp.' yet (found: '.(implode(', ', $ips) ?: 'none').').', ])->save(); return [false, 'DNS not verified yet. Add an A record for '.$domain->host.' pointing to '.$serverIp.', then try again.']; } $domain->forceFill(['dns_verified_at' => Carbon::now(), 'last_error' => null])->save(); $requested = $this->ssl->requestCertificate( $domain->host, $domain->include_www, route('api.ssl-callback'), ); if (! $requested) { $domain->forceFill(['last_error' => 'Could not reach the SSL service. Please try again shortly.'])->save(); return [false, 'Domain verified, but issuing the certificate failed. Please retry in a moment.']; } return [true, 'Domain verified. Issuing your SSL certificate — this usually takes under a minute.']; } /** Apply a signed SSL completion callback from Ladill Domains. */ public function applyCallback(string $host, string $status, ?string $expiresAt, ?string $error): void { $domain = CustomDomain::where('host', strtolower(trim($host)))->first(); if (! $domain) { return; } if ($status === 'active') { $domain->forceFill([ 'ssl_status' => CustomDomain::STATUS_ACTIVE, 'status' => CustomDomain::STATUS_ACTIVE, 'ssl_issued_at' => Carbon::now(), 'ssl_expires_at' => $expiresAt ? Carbon::parse($expiresAt) : null, 'last_error' => null, ])->save(); } else { $domain->forceFill([ 'ssl_status' => CustomDomain::STATUS_FAILED, 'status' => CustomDomain::STATUS_FAILED, 'last_error' => $error ?: 'Certificate issuance failed.', ])->save(); } } /** Resolve an incoming host to a live storefront, if any. */ public function resolveStorefront(string $host): ?QrCode { $host = preg_replace('/^www\./', '', strtolower(trim($host))); $domain = CustomDomain::where('host', $host)->where('status', CustomDomain::STATUS_ACTIVE)->first(); return $domain?->qrCode; } }