using System.Security.Claims; using api.Data; using api.Features.Auth.Common; using api.Features.Domains.Common; using api.Models; using FastEndpoints; using Microsoft.EntityFrameworkCore; namespace api.Features.Domains.Endpoints; public class VerifyDomainRequest { public Guid WorkspaceId { get; set; } public Guid Id { get; set; } } public class VerifyDomainEndpoint(AppDbContext db) : Endpoint { public override void Configure() { Post("/workspaces/{WorkspaceId}/domains/{Id}/verify"); } public override async Task HandleAsync(VerifyDomainRequest req, CancellationToken ct) { var userId = Guid.Parse(User.FindFirstValue(ClaimTypes.NameIdentifier)!); var domain = await db.Domains .Include(d => d.Workspace) .FirstOrDefaultAsync(d => d.Id == req.Id && d.WorkspaceId == req.WorkspaceId && d.Workspace.OwnerUserId == userId, ct); if (domain is null) { await HttpContext.Response.SendAsync(new MessageResponse("Domain not found"), 404, cancellation: ct); return; } // Already verified or active if (domain.Status != DomainStatus.Pending) { var alreadyResponse = new DomainVerificationResponse( domain.Id, domain.Hostname, true, domain.Status.ToString(), "Domain is already verified" ); await HttpContext.Response.SendAsync(alreadyResponse, 200, cancellation: ct); return; } // Check DNS TXT record var isVerified = await CheckDnsVerificationAsync(domain.Hostname, domain.VerificationToken); if (isVerified) { domain.Status = DomainStatus.Verified; await db.SaveChangesAsync(ct); var successResponse = new DomainVerificationResponse( domain.Id, domain.Hostname, true, domain.Status.ToString(), "Domain verified successfully" ); await HttpContext.Response.SendAsync(successResponse, 200, cancellation: ct); } else { var failedResponse = new DomainVerificationResponse( domain.Id, domain.Hostname, false, domain.Status.ToString(), $"Verification failed. Please add a TXT record for _trakqr-verification.{domain.Hostname} with value: {domain.VerificationToken}" ); await HttpContext.Response.SendAsync(failedResponse, 200, cancellation: ct); } } private static Task CheckDnsVerificationAsync(string hostname, string expectedToken) { // For testing purposes, we'll check if the domain starts with "verified-" // In production, this would be replaced with actual DNS TXT record lookup // using a library like DnsClient var isVerified = hostname.StartsWith("verified-"); return Task.FromResult(isVerified); } }