-- | This module provides functions to display errors in a fancy way. module App.DisplayErrors where import Prelude (show, ($), (<>), (==)) -- import Data.Foldable as Foldable import Data.Maybe (Maybe(..), maybe) import Halogen.HTML as HH import App.Validation.DNS as ValidationDNS import App.Validation.Login as L import App.Validation.Email as E import App.Validation.Password as P import App.Validation.Label as ValidationLabel import GenericParser.DomainParser.Common (DomainError(..)) as DomainParser import GenericParser.IPAddress as IPAddress import Web as Web error_to_paragraph :: forall w i. ValidationDNS.Error -> HH.HTML w i error_to_paragraph v = Web.error_message (Web.p $ show_error_title v) (case v of ValidationDNS.UNKNOWN -> Web.p "An internal error happened." ValidationDNS.VEIPv4 err -> maybe default_error show_error_ip4 err.error ValidationDNS.VEIPv6 err -> maybe default_error show_error_ip6 err.error ValidationDNS.VEName err -> maybe default_error show_error_domain err.error ValidationDNS.VETTL min max n -> Web.p $ "TTL should have a value between " <> show min <> " and " <> show max <> ", current value: " <> show n <> "." ValidationDNS.VEDMARCpct min max n -> Web.p $ "DMARC sample rate should have a value between " <> show min <> " and " <> show max <> ", current value: " <> show n <> "." ValidationDNS.VEDMARCri min max n -> Web.p $ "DMARC report interval should have a value between " <> show min <> " and " <> show max <> ", current value: " <> show n <> "." ValidationDNS.VETXT err -> maybe default_error show_error_txt err.error ValidationDNS.VECNAME err -> maybe default_error show_error_domain err.error ValidationDNS.VENS err -> maybe default_error show_error_domain err.error ValidationDNS.VEMX err -> maybe default_error show_error_domain err.error ValidationDNS.VEPriority min max n -> Web.p $ "Priority should have a value between " <> show min <> " and " <> show max <> ", current value: " <> show n <> "." ValidationDNS.VESRV err -> maybe default_error show_error_domain err.error ValidationDNS.VEPort min max n -> Web.p $ "Port should have a value between " <> show min <> " and " <> show max <> ", current value: " <> show n <> "." ValidationDNS.VEWeight min max n -> Web.p $ "Weight should have a value between " <> show min <> " and " <> show max <> ", current value: " <> show n <> "." ValidationDNS.VECAAflag min max n -> Web.p $ "CAA flag should have a value between " <> show min <> " and " <> show max <> ", current value: " <> show n <> "." -- SPF dedicated RR ValidationDNS.VESPFMechanismName err -> maybe default_error show_error_domain err.error ValidationDNS.VESPFMechanismIPv4 err -> maybe default_error show_error_ip4 err.error ValidationDNS.VESPFMechanismIPv6 err -> maybe default_error show_error_ip6 err.error ValidationDNS.VESPFModifierName err -> maybe default_error show_error_domain err.error ValidationDNS.DKIMInvalidKeySize min max -> show_error_key_sizes min max ) where default_error = Web.p "" show_error_key_sizes :: forall w i. Int -> Int -> HH.HTML w i show_error_key_sizes min max = if min == max then Web.p $ "Chosen signature algorithm only accepts public key input of " <> show min <> " characters." else Web.p $ "Chosen signature algorithm only accepts public key input between " <> show min <> " and " <> show max <> " characters." -- | `show_error_title` provide a simple title string to display to the user in case of an error with an entry. show_error_title :: ValidationDNS.Error -> String show_error_title v = case v of ValidationDNS.UNKNOWN -> "Unknown" ValidationDNS.VEIPv4 _ -> "Invalid IPv4 address" ValidationDNS.VEIPv6 _ -> "Invalid IPv6 address" ValidationDNS.VEName _ -> "Invalid Name (domain label)" ValidationDNS.VETTL _ _ _ -> "Invalid TTL" ValidationDNS.VEDMARCpct _ _ _ -> "Invalid DMARC sample rate" ValidationDNS.VEDMARCri _ _ _ -> "Invalid DMARC report interval" ValidationDNS.VETXT _ -> "Invalid TXT" ValidationDNS.VECNAME _ -> "Invalid CNAME" ValidationDNS.VENS _ -> "Invalid NS Target" ValidationDNS.VEMX _ -> "Invalid MX Target" ValidationDNS.VEPriority _ _ _ -> "Invalid Priority" ValidationDNS.VESRV _ -> "Invalid SRV Target" ValidationDNS.VEPort _ _ _ -> "Invalid Port" ValidationDNS.VEWeight _ _ _ -> "Invalid Weight" ValidationDNS.VECAAflag _ _ _ -> "Invalid CAA Flag" -- SPF dedicated RR ValidationDNS.VESPFMechanismName _ -> "The domain name in a SPF mechanism is wrong" ValidationDNS.VESPFMechanismIPv4 _ -> "The IPv4 address in a SPF mechanism is wrong" ValidationDNS.VESPFMechanismIPv6 _ -> "The IPv6 address in a SPF mechanism is wrong" ValidationDNS.VESPFModifierName _ -> "The domain name in a SPF modifier (EXP or REDIRECT) is wrong" ValidationDNS.DKIMInvalidKeySize _ _ -> "Public key has an invalid length" show_error_domain :: forall w i. DomainParser.DomainError -> HH.HTML w i show_error_domain e = case e of DomainParser.LabelTooLarge size -> Web.p $ "The label contains too many characters (" <> show size <> ")." DomainParser.DomainTooLarge size -> Web.p $ "The domain contains too many characters (" <> show size <> ")." -- DomainParser.InvalidCharacter -- DomainParser.EOFExpected _ -> Web.p """ The domain (or label) contains invalid characters. A domain label should start with a letter, then possibly a series of letters, digits and hyphenations ("-"), and must finish with either a letter or a digit. """ show_error_ip6 :: forall w i. IPAddress.IPv6Error -> HH.HTML w i show_error_ip6 e = case e of IPAddress.IP6TooManyHexaDecimalCharacters -> Web.p "IP6TooManyHexaDecimalCharacters" IPAddress.IP6NotEnoughChunks -> Web.p """ The IPv6 representation is erroneous, it should contain 8 groups of hexadecimal characters or being shortened with a double ':' character, such as "2000::1". """ IPAddress.IP6TooManyChunks -> Web.p "The IPv6 representation is erroneous. It should contain only up to 8 groups of hexadecimal characters." IPAddress.IP6IrrelevantShortRepresentation -> Web.p "IPv6 address has been unnecessarily shortened (with two ':')." IPAddress.IP6InvalidRange -> Web.p "IPv6 address or range isn't valid." show_error_ip4 :: forall w i. IPAddress.IPv4Error -> HH.HTML w i show_error_ip4 e = case e of IPAddress.IP4NumberTooBig n -> Web.p $ "IPv4 address contains a number too big (should be between 0 and 255). Current entered number: " <> show n IPAddress.IP4IrrelevantShortRepresentation -> Web.p "IPv4 address has been unnecessarily shortened (with two '.')." IPAddress.IP4InvalidRange -> Web.p "IPv4 address or range isn't valid." show_error_txt :: forall w i. ValidationDNS.TXTError -> HH.HTML w i show_error_txt e = case e of ValidationDNS.TXTInvalidCharacter -> Web.p "The TXT field contains some invalid characters." ValidationDNS.TXTTooLong max n -> Web.p $ "An TXT field is limited to " <> show max <> " characters (currently there are " <> show n <> " characters)." domainerror_string :: DomainParser.DomainError -> String domainerror_string (DomainParser.LabelTooLarge size) = "LabelTooLarge (size: " <> show size <> ")" domainerror_string (DomainParser.DomainTooLarge size) = "DomainTooLarge (size: " <> show size <> ")" domainerror_string (DomainParser.InvalidCharacter) = "InvalidCharacter" domainerror_string (DomainParser.EOFExpected) = "EOFExpected" -- | This `error_to_paragraph` is designed to go along the `Validation.Label` module. error_to_paragraph_label :: forall w i. ValidationLabel.Error -> HH.HTML w i error_to_paragraph_label v = Web.error_message (Web.p $ show_error_title_label v) (case v of ValidationLabel.ParsingError x -> case x.error of Nothing -> Web.p "" Just (ValidationLabel.CannotParse err) -> show_error_domain err Just (ValidationLabel.CannotEntirelyParse) -> Web.p "Cannot entirely parse the label." Just (ValidationLabel.Size min max n) -> Web.p $ "Label size should be between " <> show min <> " and " <> show max <> " (current size: " <> show n <> ")." ) show_error_title_label :: ValidationLabel.Error -> String show_error_title_label v = case v of ValidationLabel.ParsingError x -> case x.error of Nothing -> "Invalid label" Just (ValidationLabel.CannotParse _) -> "Invalid label" Just (ValidationLabel.CannotEntirelyParse) -> "Invalid label (cannot entirely parse the label)" Just (ValidationLabel.Size min max n) -> "Label size should be between " <> show min <> " and " <> show max <> " (current size: " <> show n <> ")." show_error_login :: L.Error -> String show_error_login = case _ of L.ParsingError {error} -> maybe "login is invalid, it should match the following regex: [a-zA-Z][-_ a-zA-Z0-9']*[a-zA-Z0-9]" string_error_login error string_error_login :: L.LoginParsingError -> String string_error_login = case _ of L.CannotParse -> "cannot parse the login" L.CannotEntirelyParse -> "cannot entirely parse the login" L.Size min max n -> "login size should be between " <> show min <> " and " <> show max <> " (currently: " <> show n <> ")" show_error_email :: E.Error -> String show_error_email = case _ of E.ParsingError {error} -> maybe "invalid email address" string_error_email error string_error_email :: E.EmailParsingError -> String string_error_email = case _ of E.CannotParse -> "cannot parse the email" E.CannotEntirelyParse -> "cannot entirely parse the email" E.Size min max n -> "email size should be between " <> show min <> " and " <> show max <> " (currently: " <> show n <> ")" show_error_password :: P.Error -> String show_error_password = case _ of P.ParsingError {error} -> maybe "invalid password, it should contain between 15 and 100 characters (ASCII)" string_error_password error string_error_password :: P.PasswordParsingError -> String string_error_password = case _ of P.CannotParse -> "cannot parse the password" P.CannotEntirelyParse -> "cannot entirely parse the password" P.Size min max n -> "password size should be between " <> show min <> " and " <> show max <> " (currently: " <> show n <> ")"