MCPcopy Create free account
hub / github.com/Mnexa-AI/e2a / handleVerifyDomain

Method handleVerifyDomain

internal/httpapi/domains.go:251–306  ·  view source on GitHub ↗
(ctx context.Context, in *DomainParam)

Source from the content-addressed store, hash-verified

249}
250
251func (s *Server) handleVerifyDomain(ctx context.Context, in *DomainParam) (*verifyDomainOutput, error) {
252 user, err := s.requireAccountUser(ctx)
253 if err != nil {
254 return nil, err
255 }
256 d, err := s.deps.LookupDomain(ctx, in.Domain, user.ID)
257 if err != nil || d == nil {
258 return nil, NewError(http.StatusNotFound, "not_found", "domain not found")
259 }
260 // Best-effort touch of last_checked_at — the probe runs regardless.
261 if s.deps.TouchDomainChecked != nil {
262 _ = s.deps.TouchDomainChecked(ctx, in.Domain, user.ID)
263 }
264 check := s.deps.VerifyProbe(in.Domain, d.VerificationToken, d.DKIMSelector, d.DKIMPublicKey)
265
266 // Already verified: short-circuit but surface the latest diagnostic.
267 // Still (re-)enqueue sender provisioning so this endpoint doubles as the
268 // forced sending re-check for a domain whose sending_status is pending/failed.
269 if d.Verified {
270 s.enqueueSenderProvision(ctx, d.Domain)
271 return &verifyDomainOutput{Status: http.StatusOK, Body: VerifyDomainView{
272 Domain: d.Domain, Verified: true, VerifiedAt: d.VerifiedAt,
273 MX: check.MX, SPF: check.SPF, DKIM: check.DKIM,
274 }}, nil
275 }
276 // Verification requires BOTH the ownership TXT and the inbound MX. The MX
277 // gate (added with the per-record status array) is what makes
278 // `inbound_mx.status: "verified"` honest: status is derived from the
279 // domain's `verified` flag, so `verified` must actually imply the MX is
280 // published — otherwise a TXT-only verify would claim a "verified" MX while
281 // inbound mail silently bounces. A domain can't receive mail without the MX,
282 // so requiring it for `verified` is also the correct inbound semantics.
283 // 412 with the diagnostic so callers see exactly which record is missing.
284 if !check.TXTFound || check.MX != "found" {
285 return &verifyDomainOutput{Status: http.StatusPreconditionFailed, Body: VerifyDomainView{
286 Domain: d.Domain, Verified: false, MX: check.MX, SPF: check.SPF, DKIM: check.DKIM,
287 }}, nil
288 }
289 if err := s.deps.VerifyDomain(ctx, in.Domain, user.ID); err != nil {
290 return nil, NewError(http.StatusInternalServerError, "internal_error", "failed to verify domain")
291 }
292 // Newly verified (inbound ownership): kick off SES sending-identity
293 // provisioning so the domain can graduate to own-address From.
294 s.enqueueSenderProvision(ctx, in.Domain)
295 // Re-read for verified_at; fall back to the bare success shape.
296 updated, err := s.deps.LookupDomain(ctx, in.Domain, user.ID)
297 if err != nil || updated == nil {
298 return &verifyDomainOutput{Status: http.StatusOK, Body: VerifyDomainView{
299 Domain: in.Domain, Verified: true, MX: check.MX, SPF: check.SPF, DKIM: check.DKIM,
300 }}, nil
301 }
302 return &verifyDomainOutput{Status: http.StatusOK, Body: VerifyDomainView{
303 Domain: updated.Domain, Verified: true, VerifiedAt: updated.VerifiedAt,
304 MX: check.MX, SPF: check.SPF, DKIM: check.DKIM,
305 }}, nil
306}
307
308func (s *Server) handleListDomains(ctx context.Context, _ *struct{}) (*listDomainsOutput, error) {

Callers

nothing calls this directly

Calls 5

requireAccountUserMethod · 0.95
NewErrorFunction · 0.85
LookupDomainMethod · 0.80
VerifyDomainMethod · 0.80

Tested by

no test coverage detected