ssl->configured(); } public function attach(User $user, string $host, bool $includeWww = true, bool $makeDefault = false): LinkCustomDomain { return DB::transaction(function () use ($user, $host, $includeWww, $makeDefault) { if ($makeDefault) { LinkCustomDomain::where('user_id', $user->id)->update(['is_default' => false]); } return LinkCustomDomain::create([ 'user_id' => $user->id, 'host' => $host, 'include_www' => $includeWww, 'is_default' => $makeDefault || ! LinkCustomDomain::where('user_id', $user->id)->exists(), 'status' => LinkCustomDomain::STATUS_PENDING, 'ssl_status' => LinkCustomDomain::STATUS_PENDING, ]); }); } /** @return array{0:bool,1:string} */ public function verifyAndProvision(LinkCustomDomain $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.']; } public function applyCallback(string $host, string $status, ?string $expiresAt, ?string $error): void { $domain = LinkCustomDomain::where('host', strtolower(trim($host)))->first(); if (! $domain) { return; } if ($status === 'active') { $domain->forceFill([ 'ssl_status' => LinkCustomDomain::STATUS_ACTIVE, 'status' => LinkCustomDomain::STATUS_ACTIVE, 'ssl_issued_at' => Carbon::now(), 'ssl_expires_at' => $expiresAt ? Carbon::parse($expiresAt) : null, 'last_error' => null, ])->save(); } else { $domain->forceFill([ 'ssl_status' => LinkCustomDomain::STATUS_FAILED, 'status' => LinkCustomDomain::STATUS_FAILED, 'last_error' => $error ?: 'Certificate issuance failed.', ])->save(); } } public function setDefault(LinkCustomDomain $domain): void { DB::transaction(function () use ($domain) { LinkCustomDomain::where('user_id', $domain->user_id)->update(['is_default' => false]); $domain->forceFill(['is_default' => true])->save(); }); } public function isAppHost(string $host): bool { $host = preg_replace('/^www\./', '', strtolower(trim($host))); $public = (string) config('customdomain.public_host', config('link.public_domain', 'ladl.link')); $known = array_filter([ (string) config('customdomain.app_host'), $public, 'www.'.$public, ]); return in_array($host, $known, true); } }