remove subdomain feature

This commit is contained in:
Krrish Ghimire
2026-07-06 23:03:42 +05:45
parent ad15ff8f2e
commit ea69080710
14 changed files with 24 additions and 232 deletions

View File

@@ -44,7 +44,7 @@ public class ExportController {
SiteStructure structure = llmService.restoreVersion(versions.get(0).getId());
try {
byte[] zip = exportService.exportSite(structure);
String filename = site.getSubdomain() != null ? site.getSubdomain() : site.getName().replaceAll("\\s+", "-");
String filename = site.getName().replaceAll("\\s+", "-");
return ResponseEntity.ok()
.header(HttpHeaders.CONTENT_DISPOSITION,
"attachment; filename=\"" + sanitizeFilename(filename) + "-export.zip\"")

View File

@@ -36,18 +36,12 @@ public class SiteController {
@PostMapping
public ResponseEntity<SiteResponse> createSite(@AuthenticationPrincipal UserPrincipal principal,
@Valid @RequestBody SiteRequest request) {
String subdomain = sanitizeSubdomain(request.getSubdomain());
if (subdomain != null && siteRepository.existsBySubdomain(subdomain)) {
throw new IllegalArgumentException("Subdomain already taken");
}
Site.DeploymentTarget target = parseDeploymentTarget(request.getDeploymentTarget());
Site site = Site.builder()
.userId(principal.id())
.name(request.getName())
.description(request.getDescription())
.subdomain(subdomain)
.deploymentTarget(target)
.build();
@@ -64,20 +58,12 @@ public class SiteController {
@PutMapping("/{id}")
public ResponseEntity<SiteResponse> updateSite(@AuthenticationPrincipal UserPrincipal principal,
@PathVariable UUID id,
@Valid @RequestBody SiteRequest request) {
@PathVariable UUID id,
@Valid @RequestBody SiteRequest request) {
Site site = findSiteForUser(id, principal.id());
String newSubdomain = sanitizeSubdomain(request.getSubdomain());
boolean subdomainChanged = (site.getSubdomain() != null && !site.getSubdomain().equals(newSubdomain))
|| (site.getSubdomain() == null && newSubdomain != null);
if (subdomainChanged && newSubdomain != null && siteRepository.existsBySubdomain(newSubdomain)) {
throw new IllegalArgumentException("Subdomain already taken");
}
site.setName(request.getName());
site.setDescription(request.getDescription());
site.setSubdomain(newSubdomain);
if (request.getDeploymentTarget() != null) {
site.setDeploymentTarget(parseDeploymentTarget(request.getDeploymentTarget()));
@@ -104,17 +90,6 @@ public class SiteController {
return site;
}
private String sanitizeSubdomain(String subdomain) {
if (subdomain == null || subdomain.isBlank()) {
return null;
}
String cleaned = subdomain.strip().toLowerCase();
if (!cleaned.matches("^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$")) {
throw new IllegalArgumentException("Subdomain must be 3-63 characters, lowercase alphanumeric with hyphens");
}
return cleaned;
}
private Site.DeploymentTarget parseDeploymentTarget(String value) {
if (value == null || value.isBlank()) {
return Site.DeploymentTarget.NONE;

View File

@@ -11,7 +11,5 @@ public class SiteRequest {
private String description;
private String subdomain;
private String deploymentTarget;
}

View File

@@ -18,7 +18,6 @@ public class SiteResponse {
private UUID userId;
private String name;
private String description;
private String subdomain;
private String publishedUrl;
private SiteStatus status;
private String deploymentTarget;
@@ -32,7 +31,6 @@ public class SiteResponse {
.userId(site.getUserId())
.name(site.getName())
.description(site.getDescription())
.subdomain(site.getSubdomain())
.publishedUrl(site.getPublishedUrl())
.status(site.getStatus())
.deploymentTarget(site.getDeploymentTarget().name())

View File

@@ -30,9 +30,6 @@ public class Site {
@Column(name = "description", length = 1000)
private String description;
@Column(name = "subdomain", unique = true)
private String subdomain;
@Column(name = "published_url")
private String publishedUrl;

View File

@@ -4,14 +4,9 @@ import com.krrishg.model.Site;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
public interface SiteRepository extends JpaRepository<Site, UUID> {
List<Site> findByUserIdOrderByCreatedAtDesc(UUID userId);
Optional<Site> findBySubdomain(String subdomain);
boolean existsBySubdomain(String subdomain);
}

View File

@@ -4,9 +4,6 @@ import com.krrishg.model.SelfHostedConfig;
import com.krrishg.model.Site;
import com.krrishg.repository.SelfHostedConfigRepository;
import com.krrishg.repository.SiteRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.util.Optional;
@@ -14,18 +11,13 @@ import java.util.Optional;
@Service
public class DomainService {
private static final Logger log = LoggerFactory.getLogger(DomainService.class);
private final SiteRepository siteRepository;
private final SelfHostedConfigRepository selfHostedConfigRepository;
private final String siteDomain;
public DomainService(SiteRepository siteRepository,
SelfHostedConfigRepository selfHostedConfigRepository,
@Value("${indie.domain}") String siteDomain) {
SelfHostedConfigRepository selfHostedConfigRepository) {
this.siteRepository = siteRepository;
this.selfHostedConfigRepository = selfHostedConfigRepository;
this.siteDomain = siteDomain;
}
public Optional<Site> resolveSite(String hostname) {
@@ -40,33 +32,6 @@ public class DomainService {
return siteRepository.findById(config.get().getSiteId());
}
String subdomain = extractSubdomain(lower);
if (subdomain != null) {
return siteRepository.findBySubdomain(subdomain);
}
return Optional.empty();
}
private String extractSubdomain(String hostname) {
String suffix = "." + siteDomain;
if (hostname.endsWith(suffix)) {
String subdomain = hostname.substring(0, hostname.indexOf(suffix));
if (!subdomain.isEmpty() && !subdomain.contains(".")) {
return subdomain;
}
}
return null;
}
public boolean isSubdomainAvailable(String subdomain) {
return !siteRepository.existsBySubdomain(subdomain);
}
public String getSiteUrl(Site site) {
if (site.getSubdomain() != null) {
return "https://" + site.getSubdomain() + "." + siteDomain;
}
return null;
}
}