generated from tpl/purs
feat: check wildcard addresses, retry several times to make sure that it really doesn't exist
This commit is contained in:
parent
825c35969c
commit
687a9c76b8
@ -3,6 +3,7 @@ package:
|
|||||||
- aff
|
- aff
|
||||||
- aff-promise
|
- aff-promise
|
||||||
- arrays
|
- arrays
|
||||||
|
- bifunctors
|
||||||
- effect
|
- effect
|
||||||
- either
|
- either
|
||||||
- foldable-traversable
|
- foldable-traversable
|
||||||
@ -11,6 +12,7 @@ package:
|
|||||||
- nullable
|
- nullable
|
||||||
- prelude
|
- prelude
|
||||||
- strings
|
- strings
|
||||||
|
- tailrec
|
||||||
- transformers
|
- transformers
|
||||||
- typelevel-prelude
|
- typelevel-prelude
|
||||||
name: email-address
|
name: email-address
|
||||||
|
@ -1,13 +1,16 @@
|
|||||||
module Effect.Email (EmailError(..), emailErrorToString, deliverable) where
|
module Effect.Email (EmailError(..), emailErrorCode, emailErrorToString, deliverable) where
|
||||||
|
|
||||||
import Prelude
|
import Prelude
|
||||||
|
|
||||||
import Control.Monad.Cont (lift)
|
import Control.Monad.Cont (lift)
|
||||||
import Control.Monad.Error.Class (throwError)
|
import Control.Monad.Error.Class (liftEither, throwError)
|
||||||
import Control.Monad.Except (ExceptT)
|
import Control.Monad.Except (ExceptT(..), runExceptT)
|
||||||
|
import Control.Monad.Rec.Class (Step(..), tailRecM)
|
||||||
import Control.Promise (Promise)
|
import Control.Promise (Promise)
|
||||||
import Control.Promise as Promise
|
import Control.Promise as Promise
|
||||||
import Data.Array as Array
|
import Data.Array as Array
|
||||||
|
import Data.Bifunctor (lmap)
|
||||||
|
import Data.Either (Either(..))
|
||||||
import Data.Email (Email)
|
import Data.Email (Email)
|
||||||
import Data.Email as Email
|
import Data.Email as Email
|
||||||
import Data.Eq.Generic (genericEq)
|
import Data.Eq.Generic (genericEq)
|
||||||
@ -25,14 +28,25 @@ foreign import checkEmailImpl :: String -> Effect $ Promise $ QEDResult
|
|||||||
|
|
||||||
data EmailError
|
data EmailError
|
||||||
= EmailUnreachable Email
|
= EmailUnreachable Email
|
||||||
|
| EmailWildcardExists Email
|
||||||
| EmailSyntaxInvalid Email
|
| EmailSyntaxInvalid Email
|
||||||
| EmailMXInvalid Email
|
| EmailMXInvalid Email
|
||||||
| EmailMXNoRecords Email
|
| EmailMXNoRecords Email
|
||||||
| EmailSMTPInvalid Email
|
| EmailSMTPInvalid Email
|
||||||
| EmailSMTPError Email String
|
| EmailSMTPError Email String
|
||||||
|
|
||||||
|
emailErrorCode :: EmailError -> String
|
||||||
|
emailErrorCode (EmailUnreachable _) = "email_unreachable"
|
||||||
|
emailErrorCode (EmailWildcardExists _) = "email_wildcard"
|
||||||
|
emailErrorCode (EmailSyntaxInvalid _) = "email_invalid"
|
||||||
|
emailErrorCode (EmailMXInvalid _) = "email_mx_bad"
|
||||||
|
emailErrorCode (EmailMXNoRecords _) = "email_mx_missing"
|
||||||
|
emailErrorCode (EmailSMTPInvalid _) = "email_smtp_bad"
|
||||||
|
emailErrorCode (EmailSMTPError _ _) = "email_smtp_error"
|
||||||
|
|
||||||
emailErrorToString :: EmailError -> String
|
emailErrorToString :: EmailError -> String
|
||||||
emailErrorToString (EmailUnreachable e) = "Email <" <> Email.toString e <> "> is unreachable"
|
emailErrorToString (EmailUnreachable e) = "Email <" <> Email.toString e <> "> is unreachable"
|
||||||
|
emailErrorToString (EmailWildcardExists e) = "Wildcard address <*." <> Email.domain e <> "> is registered; cannot definitively say if <" <> Email.toString e <> "> exists."
|
||||||
emailErrorToString (EmailSyntaxInvalid e) = "Email <" <> Email.toString e <> "> is invalid"
|
emailErrorToString (EmailSyntaxInvalid e) = "Email <" <> Email.toString e <> "> is invalid"
|
||||||
emailErrorToString (EmailMXInvalid e) = "Email <" <> Email.toString e <> "> domain has invalid MX record"
|
emailErrorToString (EmailMXInvalid e) = "Email <" <> Email.toString e <> "> domain has invalid MX record"
|
||||||
emailErrorToString (EmailMXNoRecords e) = "Email <" <> Email.toString e <> "> domain has no MX records"
|
emailErrorToString (EmailMXNoRecords e) = "Email <" <> Email.toString e <> "> domain has no MX records"
|
||||||
@ -64,10 +78,9 @@ type QEDResult =
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
deliverable :: Email -> ExceptT EmailError Aff Email
|
deliverableOnce :: Email -> ExceptT EmailError Aff Email
|
||||||
deliverable email' = do
|
deliverableOnce email' = do
|
||||||
let email = Email.toString email'
|
let email = Email.toString email'
|
||||||
|
|
||||||
{ reachable, syntax, mx, smtp } <- lift $ Promise.toAffE $ checkEmailImpl email
|
{ reachable, syntax, mx, smtp } <- lift $ Promise.toAffE $ checkEmailImpl email
|
||||||
when (not reachable) $ throwError $ EmailUnreachable email'
|
when (not reachable) $ throwError $ EmailUnreachable email'
|
||||||
when (not syntax.valid) $ throwError $ EmailSyntaxInvalid email'
|
when (not syntax.valid) $ throwError $ EmailSyntaxInvalid email'
|
||||||
@ -75,5 +88,24 @@ deliverable email' = do
|
|||||||
when (not smtp.valid) $ throwError $ EmailSMTPInvalid email'
|
when (not smtp.valid) $ throwError $ EmailSMTPInvalid email'
|
||||||
when (maybe true Array.null $ Nullable.toMaybe $ mx.mxRecords) $ throwError $ EmailMXNoRecords email'
|
when (maybe true Array.null $ Nullable.toMaybe $ mx.mxRecords) $ throwError $ EmailMXNoRecords email'
|
||||||
for_ (Nullable.toMaybe $ smtp.error) $ throwError <<< EmailSMTPError email'
|
for_ (Nullable.toMaybe $ smtp.error) $ throwError <<< EmailSMTPError email'
|
||||||
|
|
||||||
pure email'
|
pure email'
|
||||||
|
|
||||||
|
deliverable :: Email -> ExceptT EmailError Aff Email
|
||||||
|
deliverable email' =
|
||||||
|
let
|
||||||
|
attempt n
|
||||||
|
| n < 10 =
|
||||||
|
do
|
||||||
|
res <- runExceptT $ deliverableOnce email'
|
||||||
|
case res of
|
||||||
|
Left (EmailUnreachable _) -> pure $ Loop $ n + 1
|
||||||
|
Left e -> pure $ Done $ Left e
|
||||||
|
Right ok -> pure $ Done $ Right ok
|
||||||
|
| otherwise = pure $ Done $ Left $ EmailUnreachable email'
|
||||||
|
in
|
||||||
|
do
|
||||||
|
wildcard <- liftEither $ lmap (const $ EmailSyntaxInvalid email') $ Email.parse $ "*@" <> Email.domain email'
|
||||||
|
res <- lift $ runExceptT $ deliverableOnce wildcard
|
||||||
|
case res of
|
||||||
|
Right _ -> throwError $ EmailWildcardExists email'
|
||||||
|
_ -> ExceptT $ tailRecM attempt 0
|
||||||
|
Loading…
Reference in New Issue
Block a user