File indexing completed on 2024-04-14 14:18:29

0001 /*
0002     SPDX-FileCopyrightText: 2004 Matt Douhan <matt@fruitsalad.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 /**
0008   @file
0009   This file provides static methods for email address validation.
0010 
0011   @brief Email address validation methods.
0012 
0013   @author Matt Douhan \<matt@fruitsalad.org\>
0014  */
0015 
0016 #ifndef KCODECS_EMAILADDRESS_H
0017 #define KCODECS_EMAILADDRESS_H
0018 
0019 #include <QUrl>
0020 
0021 #include <QByteArray>
0022 #include <QStringList>
0023 
0024 #include <kcodecs_export.h>
0025 
0026 /**
0027  * @since 5.5.0
0028  */
0029 namespace KEmailAddress
0030 {
0031 /**
0032   @defgroup emailvalidation Email Validation Functions
0033 
0034   This collection of methods that can validate email addresses as supplied
0035   by the user (typically, user input from a text box). There are also
0036   functions for splitting an RFC2822 address into its component parts.
0037 
0038   @{
0039 */
0040 
0041 /**
0042   Email validation result. The only 'success' code in
0043   this enumeration is AddressOK; all the other values
0044   indicate some specific problem with the address which
0045   is being validated.
0046 
0047   Result type for splitAddress(), isValidAddress()
0048   and isValidSimpleAddress().
0049 */
0050 enum EmailParseResult {
0051     AddressOk, /**< Email is valid */
0052     AddressEmpty, /**< The address is empty */
0053     UnexpectedEnd, /**< Something is unbalanced */
0054     UnbalancedParens, /**< Unbalanced ( ) */
0055     MissingDomainPart, /**< No domain in address */
0056     UnclosedAngleAddr, /**< \< with no matching \> */
0057     UnopenedAngleAddr, /**< \> with no preceding \< */
0058     TooManyAts, /**< More than one \@ in address */
0059     UnexpectedComma, /**< Comma not allowed here */
0060     TooFewAts, /**< Missing \@ in address */
0061     MissingLocalPart, /**< No address specified, only domain */
0062     UnbalancedQuote, /**< Quotes (single or double) not matched */
0063     NoAddressSpec,
0064     DisallowedChar, /**< An invalid character detected in address */
0065     InvalidDisplayName, /**< An invalid displayname detected in address */
0066     TooFewDots, /**< Missing \. in address */
0067 };
0068 
0069 /** Split a comma separated list of email addresses.
0070 
0071 @param aStr a single string representing a list of addresses
0072 @return a list of strings, where each string is one address
0073 from the original list
0074 */
0075 KCODECS_EXPORT
0076 QStringList splitAddressList(const QString &aStr);
0077 
0078 /**
0079   Splits the given address into display name, email address and comment.
0080   Returns AddressOk if no error was encountered. Otherwise an appropriate
0081   error code is returned. In case of an error the values of displayName,
0082   addrSpec and comment are undefined.
0083 
0084   @param address      a single email address,
0085   example: Joe User (comment1) <joe.user@example.org> (comment2)
0086   @param displayName  only out: the display-name of the email address, i.e.
0087   "Joe User" in the example; in case of an error the
0088   return value is undefined
0089   @param addrSpec     only out: the addr-spec, i.e. "joe.user@example.org"
0090   in the example; in case of an error the return value is undefined
0091   @param comment      only out: the space-separated comments, i.e.
0092   "comment1 comment2" in the example; in case of an
0093   error the return value is undefined
0094 
0095   @return             AddressOk if no error was encountered. Otherwise an
0096   appropriate error code is returned.
0097 */
0098 KCODECS_EXPORT
0099 EmailParseResult splitAddress(const QByteArray &address, QByteArray &displayName, QByteArray &addrSpec, QByteArray &comment);
0100 
0101 /**
0102   This is an overloaded member function, provided for convenience.
0103   It behaves essentially like the above function.
0104 
0105   Splits the given address into display name, email address and comment.
0106   Returns AddressOk if no error was encountered. Otherwise an appropriate
0107   error code is returned. In case of an error the values of displayName,
0108   addrSpec and comment are undefined.
0109 
0110   @param address      a single email address,
0111   example: Joe User (comment1) <joe.user@example.org> (comment2)
0112   @param displayName  only out: the display-name of the email address, i.e.
0113   "Joe User" in the example; in case of an error the
0114   return value is undefined
0115   @param addrSpec     only out: the addr-spec, i.e. "joe.user@example.org"
0116   in the example; in case of an error the return value is undefined
0117   @param comment      only out: the space-separated comments, i.e.
0118   "comment1 comment2" in the example; in case of an
0119   error the return value is undefined
0120 
0121   @return             AddressOk if no error was encountered. Otherwise an
0122   appropriate error code is returned.
0123 */
0124 KCODECS_EXPORT
0125 EmailParseResult splitAddress(const QString &address, QString &displayName, QString &addrSpec, QString &comment);
0126 
0127 /**
0128   Validates an email address in the form of "Joe User" <joe@example.org>.
0129   Returns AddressOk if no error was encountered. Otherwise an appropriate
0130   error code is returned.
0131 
0132   @param aStr         a single email address,
0133   example: Joe User (comment1) <joe.user@example.org>
0134   @return             AddressOk if no error was encountered. Otherwise an
0135   appropriate error code is returned.
0136 */
0137 KCODECS_EXPORT
0138 EmailParseResult isValidAddress(const QString &aStr);
0139 
0140 /**
0141   Validates a list of email addresses, and also allow aliases and
0142   distribution lists to be expanded before validation.
0143 
0144   @param aStr         a string containing a list of email addresses.
0145   @param badAddr      a string to hold the address that was faulty.
0146 
0147   @return AddressOk if no error was encountered. Otherwise an
0148   appropriate error code is returned.
0149 */
0150 KCODECS_EXPORT
0151 EmailParseResult isValidAddressList(const QString &aStr, QString &badAddr);
0152 
0153 /**
0154   Translate the enum errorcodes from emailParseResult
0155   into i18n'd strings that can be used for msg boxes.
0156 
0157   @param errorCode an @em error code returned from one of the
0158   email validation functions. Do not pass
0159   AddressOk as a value, since that will yield
0160   a misleading error message
0161 
0162   @return human-readable and already translated message describing
0163   the validation error.
0164 */
0165 KCODECS_EXPORT
0166 QString emailParseResultToString(EmailParseResult errorCode);
0167 
0168 /**
0169   Validates an email address in the form of joe@example.org.
0170   Returns true if no error was encountered.
0171   This method should be used when the input field should not
0172   allow a "full" email address with comments and other special
0173   cases that normally are valid in an email address.
0174 
0175   @param aStr         a single email address,
0176   example: joe.user@example.org
0177 
0178   @return             true if no error was encountered.
0179 
0180   @note This method differs from calling isValidAddress()
0181   and checking that that returns AddressOk in two ways:
0182   it is faster, and it does @em not allow fancy addresses.
0183 */
0184 KCODECS_EXPORT
0185 bool isValidSimpleAddress(const QString &aStr);
0186 
0187 /**
0188   Returns a i18n string to be used in msgboxes. This allows for error
0189   messages to be the same across the board.
0190 
0191   @return             An i18n ready string for use in msgboxes.
0192 */
0193 
0194 KCODECS_EXPORT
0195 QString simpleEmailAddressErrorMsg();
0196 
0197 /** @}  */
0198 
0199 /** @defgroup emailextraction Email Extraction Functions
0200     @{
0201 */
0202 
0203 /**
0204   Returns the pure email address (addr-spec in RFC2822) of the given address
0205   (mailbox in RFC2822).
0206 
0207   @param address  an email address, e.g. "Joe User <joe.user@example.org>"
0208   @return         the addr-spec of @a address, i.e. joe.user@example.org
0209   in the example
0210 */
0211 KCODECS_EXPORT
0212 QByteArray extractEmailAddress(const QByteArray &address);
0213 
0214 /*KF6 merge with above*/
0215 
0216 /**
0217   Returns the pure email address (addr-spec in RFC2822) of the given address
0218   (mailbox in RFC2822).
0219 
0220   @param address  an email address, e.g. "Joe User <joe.user@example.org>"
0221   @param errorMessage return error message when we can't parse email
0222   @return         the addr-spec of @a address, i.e. joe.user@example.org
0223   in the example
0224   @since 5.11.0
0225 
0226 */
0227 KCODECS_EXPORT
0228 QByteArray extractEmailAddress(const QByteArray &address, QString &errorMessage);
0229 
0230 /**
0231   This is an overloaded member function, provided for convenience.
0232   It behaves essentially like the above function.
0233 
0234   Returns the pure email address (addr-spec in RFC2822) of the given
0235   address (mailbox in RFC2822).
0236 
0237   @param address  an email address, e.g. "Joe User <joe.user@example.org>"
0238   @return         the addr-spec of @a address, i.e. joe.user@example.org
0239   in the example
0240 */
0241 KCODECS_EXPORT
0242 QString extractEmailAddress(const QString &address);
0243 
0244 /**
0245   Returns the pure email address (addr-spec in RFC2822) of the first
0246   email address of a list of addresses.
0247 
0248   @param addresses an email address, e.g. "Joe User <joe.user@example.org>"
0249   @param errorMessage return error message when we can't parse email
0250   @return          the addr-spec of @a addresses, i.e. joe.user@example.org
0251   in the example
0252   @since 5.11
0253 */
0254 
0255 KCODECS_EXPORT
0256 QString extractEmailAddress(const QString &address, QString &errorMessage);
0257 
0258 /**
0259   Returns the pure email address (addr-spec in RFC2822) of the first
0260   email address of a list of addresses.
0261 
0262   @param addresses an email address, e.g. "Joe User <joe.user@example.org>"
0263   @return          the addr-spec of @a addresses, i.e. joe.user@example.org
0264   in the example
0265 */
0266 
0267 /*KF6 merge with above*/
0268 KCODECS_EXPORT
0269 QByteArray firstEmailAddress(const QByteArray &addresses);
0270 
0271 /**
0272   Returns the pure email address (addr-spec in RFC2822) of the first
0273   email address of a list of addresses.
0274 
0275   @param addresses an email address, e.g. "Joe User <joe.user@example.org>"
0276   @param errorMessage return error message when we can't parse email
0277   @return          the addr-spec of @a addresses, i.e. joe.user@example.org
0278   in the example
0279   @since 5.11.0
0280 */
0281 
0282 KCODECS_EXPORT
0283 QByteArray firstEmailAddress(const QByteArray &addresses, QString &errorMessage);
0284 
0285 /**
0286   This is an overloaded member function, provided for convenience.
0287   It behaves essentially like the above function.
0288 
0289   Returns the pure email address (addr-spec in RFC2822) of the first
0290   email address of a list of addresses.
0291 
0292   @param addresses an email address, e.g. "Joe User <joe.user@example.org>"
0293   @return          the addr-spec of @a addresses, i.e. joe.user@example.org
0294   in the example
0295 */
0296 KCODECS_EXPORT
0297 QString firstEmailAddress(const QString &addresses);
0298 
0299 /**
0300   This is an overloaded member function, provided for convenience.
0301   It behaves essentially like the above function.
0302 
0303   Returns the pure email address (addr-spec in RFC2822) of the first
0304   email address of a list of addresses.
0305 
0306   @param addresses an email address, e.g. "Joe User <joe.user@example.org>"
0307   @param errorMessage return error message when we can't parse email
0308   @return          the addr-spec of @a addresses, i.e. joe.user@example.org
0309   in the example
0310   @since 5.11.0
0311 */
0312 KCODECS_EXPORT
0313 QString firstEmailAddress(const QString &addresses, QString &errorMessage);
0314 
0315 /**
0316   Return email address and name from string.
0317   Examples:
0318     "Stefan Taferner <taferner@example.org>" returns "taferner@example.org"
0319     and "Stefan Taferner". "joe@example.com" returns "joe@example.com"
0320     and "". Note that this only returns the first address.
0321 
0322   Also note that the return value is true if both the name and the
0323   mail are not empty: this does NOT tell you if mail contains a
0324   valid email address or just some rubbish.
0325 
0326   @param aStr  an email address, e.g "Joe User <joe.user@example.org>"
0327   @param name  only out: returns the displayname, "Joe User" in the example
0328   @param mail  only out: returns the email address "joe.user@example.org"
0329   in the example
0330 
0331   @return true if both name and email address are not empty
0332 */
0333 KCODECS_EXPORT
0334 bool extractEmailAddressAndName(const QString &aStr, QString &mail, QString &name);
0335 
0336 /**
0337   Compare two email addresses. If matchName is false, it just checks
0338   the email address, and returns true if this matches. If matchName
0339   is true, both the name and the email must be the same.
0340 
0341   @param email1  the first email address to use for comparison
0342   @param email2  the second email address to use for comparison
0343   @param matchName  if set to true email address and displayname must match
0344 
0345   @return true if the comparison matches true in all other cases
0346 */
0347 KCODECS_EXPORT
0348 bool compareEmail(const QString &email1, const QString &email2, bool matchName);
0349 
0350 /**
0351   Returns a normalized address built from the given parts. The normalized
0352   address is of one the following forms:
0353     - displayName (comment) &lt;addrSpec&gt;
0354     - displayName &lt;addrSpec&gt;
0355     - comment &lt;addrSpec&gt;
0356     - addrSpec
0357 
0358   @param displayName  the display name of the address
0359   @param addrSpec     the actual email address (addr-spec in RFC 2822)
0360   @param comment      a comment
0361 
0362   @return             a normalized address built from the given parts
0363 */
0364 KCODECS_EXPORT
0365 QString normalizedAddress(const QString &displayName, const QString &addrSpec, const QString &comment = QString());
0366 
0367 /** @} */
0368 
0369 /** @defgroup emailidn Email IDN (punycode) handling
0370     @{
0371 */
0372 
0373 /**
0374   Decodes the punycode domain part of the given addr-spec if it's an IDN.
0375 
0376   @param addrSpec  a pure 7-bit email address (addr-spec in RFC2822)
0377   @return          the email address with Unicode domain
0378 */
0379 KCODECS_EXPORT
0380 QString fromIdn(const QString &addrSpec);
0381 
0382 /**
0383   Encodes the domain part of the given addr-spec in punycode if it's an IDN.
0384 
0385   @param addrSpec  a pure email address with Unicode domain
0386   @return          the email address with domain in punycode
0387 */
0388 KCODECS_EXPORT
0389 QString toIdn(const QString &addrSpec);
0390 
0391 /**
0392   Normalizes all email addresses in the given list and decodes all IDNs.
0393 
0394   @param addresses  a list of email addresses with punycoded IDNs
0395   @return           the email addresses in normalized form with Unicode IDNs
0396 */
0397 KCODECS_EXPORT
0398 QString normalizeAddressesAndDecodeIdn(const QString &addresses);
0399 
0400 /**
0401   Normalizes all email addresses in the given list and encodes all IDNs
0402   in punycode.
0403 
0404   @param str  a list of email addresses
0405   @return     the email addresses in normalized form
0406 */
0407 KCODECS_EXPORT
0408 QString normalizeAddressesAndEncodeIdn(const QString &str);
0409 
0410 /** @} */
0411 
0412 /** @ingroup emailextraction
0413 
0414   Add quote characters around the given string if it contains a
0415   character that makes that necessary, in an email name, such as ",".
0416 
0417   @param str  a string that may need quoting
0418   @return     the string quoted if necessary
0419 */
0420 KCODECS_EXPORT
0421 QString quoteNameIfNecessary(const QString &str);
0422 
0423 /**
0424  * Creates a valid mailto: URL from the given mailbox.
0425  * @param mailbox The mailbox, which means the display name and the address specification, for
0426  *                example "Thomas McGuire" <thomas@domain.com>. The display name is optional.
0427  * @return a valid mailto: URL for the given mailbox.
0428  */
0429 KCODECS_EXPORT
0430 QUrl encodeMailtoUrl(const QString &mailbox);
0431 
0432 /**
0433  * Extracts the mailbox out of the mailto: URL.
0434  * @param mailtoUrl the URL with the mailto protocol, which contains the mailbox to be extracted
0435  * @return the mailbox, which means the display name and the address specification.
0436  */
0437 KCODECS_EXPORT
0438 QString decodeMailtoUrl(const QUrl &mailtoUrl);
0439 
0440 } // namespace KEmailAddress
0441 
0442 #endif