рдИрдореЗрд▓ рд╕рддреНрдпрд╛рдкрди рдЖрдзреБрдирд┐рдХ рд╡реЗрдм рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХрд╛ рдПрдХ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдШрдЯрдХ рд╣реИ рдЬрд┐рд╕реЗ рд╣рд░ рдбреЗрд╡рд▓рдкрд░ рдХреЛ рд╕рд╣реА рддрд░реАрдХреЗ рд╕реЗ рд╕рдордЭрдирд╛ рдФрд░ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред рдЪрд╛рд╣реЗ рдЖрдк рдПрдХ рдпреВрдЬрд░ рд░рдЬрд┐рд╕реНрдЯреНрд░реЗрд╢рди рд╕рд┐рд╕реНрдЯрдо рдмрдирд╛ рд░рд╣реЗ рд╣реЛрдВ, рдиреНрдпреВрдЬрд╝рд▓реЗрдЯрд░ рдкреНрд▓реЗрдЯрдлрд╝реЙрд░реНрдо рдмрдирд╛ рд░рд╣реЗ рд╣реЛрдВ, рдпрд╛ рдПрдХ рдИ-рдХреЙрдорд░реНрд╕ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдмрдирд╛ рд░рд╣реЗ рд╣реЛрдВ, рдордЬрдмреВрдд рдИрдореЗрд▓ рд╕рддреНрдпрд╛рдкрди рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рдЖрдкрдХреЗ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЛ рдЕрдорд╛рдиреНрдп рдбреЗрдЯрд╛ рд╕реЗ рдмрдЪрд╛рддрд╛ рд╣реИ, рдмрд╛рдЙрдВрд╕ рд░реЗрдЯ рдХреЛ рдХрдо рдХрд░рддрд╛ рд╣реИ, рдФрд░ рд╕рдордЧреНрд░ рдбрд┐рд▓реАрд╡рд░реЗрдмрд┐рд▓рд┐рдЯреА рдореЗрдВ рд╕реБрдзрд╛рд░ рдХрд░рддрд╛ рд╣реИред рдпрд╣ рд╡реНрдпрд╛рдкрдХ рдЧрд╛рдЗрдб рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХреЛ рд╕реНрдХреНрд░реИрдЪ рд╕реЗ рдкреНрд░реЛрдлреЗрд╢рдирд▓-рдЧреНрд░реЗрдб рдИрдореЗрд▓ рд╕рддреНрдпрд╛рдкрди рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рд╕рдм рдХреБрдЫ рдкреНрд░рджрд╛рди рдХрд░рддреА рд╣реИред
рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХреЛ рдИрдореЗрд▓ рд╕рддреНрдпрд╛рдкрди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХреНрдпреЛрдВ рд╣реИ
рдИрдореЗрд▓ рд╕рддреНрдпрд╛рдкрди рдХреЗ рдорд╣рддреНрд╡ рдХреЛ рд╕рдордЭрдиреЗ рд╕реЗ рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХреЛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд░рдгрдиреАрддрд┐рдпреЛрдВ рдФрд░ рд╕рдВрд╕рд╛рдзрди рдЖрд╡рдВрдЯрди рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕реВрдЪрд┐рдд рдирд┐рд░реНрдгрдп рд▓реЗрдиреЗ рдореЗрдВ рдорджрдж рдорд┐рд▓рддреА рд╣реИред
рдИрдореЗрд▓ рд╕рддреНрдпрд╛рдкрди рдХреЗ рд▓рд┐рдП рдмрд┐рдЬрдиреЗрд╕ рдХреЗрд╕
рдЕрдорд╛рдиреНрдп рдИрдореЗрд▓ рдкрддреЗ рд╡рд╛рд░реНрд╖рд┐рдХ рд░реВрдк рд╕реЗ рдмрд░реНрдмрд╛рдж рдорд╛рд░реНрдХреЗрдЯрд┐рдВрдЧ рдЦрд░реНрдЪ, рдХреНрд╖рддрд┐рдЧреНрд░рд╕реНрдд рд╕реЗрдВрдбрд░ рдкреНрд░рддрд┐рд╖реНрдард╛ рдФрд░ рдЦреЛрдП рд╣реБрдП рдЧреНрд░рд╛рд╣рдХ рдЬреБрдбрд╝рд╛рд╡ рдХреЗ рдЕрд╡рд╕рд░реЛрдВ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╡реНрдпрд╡рд╕рд╛рдпреЛрдВ рдХреЛ рд▓рд╛рдЦреЛрдВ рдбреЙрд▓рд░ рдХрд╛ рдиреБрдХрд╕рд╛рди рдкрд╣реБрдВрдЪрд╛рддреЗ рд╣реИрдВред рдЬрдм рдпреВрдЬрд░реНрд╕ рд░рдЬрд┐рд╕реНрдЯреНрд░реЗрд╢рди рдХреЗ рджреМрд░рд╛рди рдЧрд▓рдд рдИрдореЗрд▓ рдкрддреЗ рджрд░реНрдЬ рдХрд░рддреЗ рд╣реИрдВ, рдЪрд╛рд╣реЗ рдЯрд╛рдЗрдкреЛ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдпрд╛ рдЬрд╛рдирдмреВрдЭрдХрд░ рдирдХрд▓реА рдкрддреЛрдВ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ, рдкрд░рд┐рдгрд╛рдо рдЖрдкрдХреЗ рдкреВрд░реЗ рд╕рд┐рд╕реНрдЯрдо рдореЗрдВ рдлреИрд▓рддреЗ рд╣реИрдВред
Gmail, Outlook рдФрд░ Yahoo рдЬреИрд╕реЗ рдИрдореЗрд▓ рд╕реЗрд╡рд╛ рдкреНрд░рджрд╛рддрд╛ рд╕реЗрдВрдбрд░ рдкреНрд░рддрд┐рд╖реНрдард╛ рдореЗрдЯреНрд░рд┐рдХреНрд╕ рдХреА рдмрд╛рд░реАрдХреА рд╕реЗ рдирд┐рдЧрд░рд╛рдиреА рдХрд░рддреЗ рд╣реИрдВред рдЬрдм рдЖрдкрдХрд╛ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдЕрдорд╛рдиреНрдп рдкрддреЛрдВ рдкрд░ рдИрдореЗрд▓ рднреЗрдЬрддрд╛ рд╣реИ, рддреЛ рдпреЗ рдмрд╛рдЙрдВрд╕ рд╣реЛ рдЬрд╛рддреЗ рд╣реИрдВ рдФрд░ рдЖрдкрдХреЗ рд╕реЗрдВрдбрд░ рд╕реНрдХреЛрд░ рдХреЛ рдирдХрд╛рд░рд╛рддреНрдордХ рд░реВрдк рд╕реЗ рдкреНрд░рднрд╛рд╡рд┐рдд рдХрд░рддреЗ рд╣реИрдВред рдПрдХ рдЦрд░рд╛рдм рд╕реЗрдВрдбрд░ рдкреНрд░рддрд┐рд╖реНрдард╛ рдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рдЖрдкрдХреЗ рд╡реИрдз рдИрдореЗрд▓ рддреЗрдЬреА рд╕реЗ рд╕реНрдкреИрдо рдлрд╝реЛрд▓реНрдбрд░реЛрдВ рдореЗрдВ рдкрд╣реБрдВрдЪрддреЗ рд╣реИрдВ, рдЬрд┐рд╕рд╕реЗ рдЖрдкрдХреЗ рд╕рднреА рдИрдореЗрд▓ рд╕рдВрдЪрд╛рд░ рдХреА рдкреНрд░рднрд╛рд╡рд╢реАрд▓рддрд╛ рдХрдо рд╣реЛ рдЬрд╛рддреА рд╣реИред
рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХреЗ рд▓рд┐рдП, рдПрдВрдЯреНрд░реА рдкреЙрдЗрдВрдЯ рдкрд░ рдИрдореЗрд▓ рд╕рддреНрдпрд╛рдкрди рд▓рд╛рдЧреВ рдХрд░рдиреЗ рд╕реЗ рдпреЗ рд╕рдорд╕реНрдпрд╛рдПрдВ рд╣реЛрдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рд╣реА рд░реЛрдХ рджреА рдЬрд╛рддреА рд╣реИрдВред рдпреВрдЬрд░ рд╕рд╛рдЗрдирдЕрдк рдХреЗ рджреМрд░рд╛рди рд╡рд╛рд╕реНрддрд╡рд┐рдХ рд╕рдордп рдореЗрдВ рдИрдореЗрд▓ рдкрддреЛрдВ рдХреЛ рдорд╛рдиреНрдп рдХрд░рдХреЗ, рдЖрдк рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ рдЖрдкрдХреЗ рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рд╢реБрд░реБрдЖрдд рд╕реЗ рд╣реА рдХреЗрд╡рд▓ рд╡реИрдз, рдбрд┐рд▓реАрд╡рд░ рдХрд░рдиреЗ рдпреЛрдЧреНрдп рдкрддреЗ рд╣реЛрдВред
рдИрдореЗрд▓ рд╕рддреНрдпрд╛рдкрди рдХреЗ рддрдХрдиреАрдХреА рд▓рд╛рдн
рдмрд┐рдЬрдиреЗрд╕ рдореЗрдЯреНрд░рд┐рдХреНрд╕ рд╕реЗ рдкрд░реЗ, рдИрдореЗрд▓ рд╕рддреНрдпрд╛рдкрди рдорд╣рддреНрд╡рдкреВрд░реНрдг рддрдХрдиреАрдХреА рд▓рд╛рдн рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ рдЬреЛ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреА рдЧреБрдгрд╡рддреНрддрд╛ рдФрд░ рд╡рд┐рд╢реНрд╡рд╕рдиреАрдпрддрд╛ рдореЗрдВ рд╕реБрдзрд╛рд░ рдХрд░рддреЗ рд╣реИрдВред рд╕рд╛рдл рдИрдореЗрд▓ рдбреЗрдЯрд╛ рдирдХрд▓реА рдЦрд╛рддреЛрдВ рд╕реЗ рдбреЗрдЯрд╛рдмреЗрд╕ рдмреНрд▓реЛрдЯ рдХреЛ рдХрдо рдХрд░рддрд╛ рд╣реИ, рдХреНрд╡реЗрд░реА рдкреНрд░рджрд░реНрд╢рди рдореЗрдВ рд╕реБрдзрд╛рд░ рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдпреВрдЬрд░ рдкреНрд░рдмрдВрдзрди рдХреЛ рд╕рд░рд▓ рдмрдирд╛рддрд╛ рд╣реИред
рдИрдореЗрд▓ рд╕рддреНрдпрд╛рдкрди рдЕрдХрд╛рдЙрдВрдЯ рдПрдиреНрдпреВрдорд░реЗрд╢рди рд╣рдорд▓реЛрдВ рдХреЛ рд░реЛрдХрдХрд░ рдФрд░ рдмреЙрдЯ рд░рдЬрд┐рд╕реНрдЯреНрд░реЗрд╢рди рдХреА рдкреНрд░рднрд╛рд╡рд╢реАрд▓рддрд╛ рдХреЛ рдХрдо рдХрд░рдХреЗ рд╕реБрд░рдХреНрд╖рд╛ рдХреЛ рднреА рдмрдврд╝рд╛рддрд╛ рд╣реИред рдЬрдм рд░реЗрдЯ рд▓рд┐рдорд┐рдЯрд┐рдВрдЧ рдФрд░ CAPTCHA рдЬреИрд╕реЗ рдЕрдиреНрдп рд╕реБрд░рдХреНрд╖рд╛ рдЙрдкрд╛рдпреЛрдВ рдХреЗ рд╕рд╛рде рд╕рдВрдпреБрдХреНрдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдИрдореЗрд▓ рд╕рддреНрдпрд╛рдкрди рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рджреБрд░реБрдкрдпреЛрдЧ рдХреЗ рдЦрд┐рд▓рд╛рдл рдПрдХ рдордЬрдмреВрдд рд░рдХреНрд╖рд╛ рдмрдирд╛рддрд╛ рд╣реИред
рдИрдореЗрд▓ рд╕рддреНрдпрд╛рдкрди рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ рдЕрд╡рд▓реЛрдХрди
рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╡рд┐рд╡рд░рдг рдореЗрдВ рдЧреЛрддрд╛ рд▓рдЧрд╛рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ, рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХреЛ рдкреВрд░реНрдг рдИрдореЗрд▓ рд╕рддреНрдпрд╛рдкрди рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ рдФрд░ рд╡рд┐рднрд┐рдиреНрди рдШрдЯрдХ рдПрдХ рд╕рд╛рде рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВ, рдпрд╣ рд╕рдордЭрдирд╛ рдЪрд╛рд╣рд┐рдПред рдИ-рдХреЙрдорд░реНрд╕ applications рдХреЗ рд▓рд┐рдП, E-commerce Implementation Guide рджреЗрдЦреЗрдВред
рдорд▓реНрдЯреА-рд▓реЗрдпрд░ рд╕рддреНрдпрд╛рдкрди рджреГрд╖реНрдЯрд┐рдХреЛрдг
рдкреНрд░реЛрдлреЗрд╢рдирд▓ рдИрдореЗрд▓ рд╕рддреНрдпрд╛рдкрди рд╕рд┐рд╕реНрдЯрдо рдХрдИ рд╕рддреНрдпрд╛рдкрди рд▓реЗрдпрд░ рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВ, рдкреНрд░рддреНрдпреЗрдХ рд╡рд┐рднрд┐рдиреНрди рдкреНрд░рдХрд╛рд░ рдХреЗ рдЕрдорд╛рдиреНрдп рдкрддреЛрдВ рдХреЛ рдкрдХрдбрд╝рддреА рд╣реИред рдпрд╣ рд▓реЗрдпрд░реНрдб рджреГрд╖реНрдЯрд┐рдХреЛрдг рдкреНрд░рджрд░реНрд╢рди рдХреЛ рдЕрдиреБрдХреВрд▓рд┐рдд рдХрд░рддреЗ рд╣реБрдП рд╕рдЯреАрдХрддрд╛ рдХреЛ рдЕрдзрд┐рдХрддрдо рдХрд░рддрд╛ рд╣реИред
рдкрд╣рд▓реА рд▓реЗрдпрд░ рд╕рд┐рдВрдЯреИрдХреНрд╕ рд╕рддреНрдпрд╛рдкрди рдХрд░рддреА рд╣реИ, рдпрд╣ рдЬрд╛рдВрдЪрддреА рд╣реИ рдХрд┐ рдИрдореЗрд▓ рдкрддреЗ RFC 5321 рдФрд░ RFC 5322 рдорд╛рдирдХреЛрдВ рдХреЗ рдЕрдиреБрд░реВрдк рд╣реИрдВред рдпрд╣ рддреЗрдЬ, рд╕реНрдерд╛рдиреАрдп рд╕рддреНрдпрд╛рдкрди рдмрд┐рдирд╛ рдХрд┐рд╕реА рдиреЗрдЯрд╡рд░реНрдХ рдЕрдиреБрд░реЛрдз рдХреЗ рд╕реНрдкрд╖реНрдЯ рдлрд╝реЙрд░реНрдореЗрдЯрд┐рдВрдЧ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рдкрдХрдбрд╝рддрд╛ рд╣реИред
рджреВрд╕рд░реА рд▓реЗрдпрд░ DNS рд╕рддреНрдпрд╛рдкрди рдХрд░рддреА рд╣реИ, MX рд░рд┐рдХреЙрд░реНрдб рдХреЛ рдХреНрд╡реЗрд░реА рдХрд░рдХреЗ рдпрд╣ рд╕рддреНрдпрд╛рдкрд┐рдд рдХрд░рддреА рд╣реИ рдХрд┐ рдИрдореЗрд▓ рдбреЛрдореЗрди рдореЗрд▓ рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддрд╛ рд╣реИред рдпрд╣ рдиреЗрдЯрд╡рд░реНрдХ-рдЖрдзрд╛рд░рд┐рдд рд╕рддреНрдпрд╛рдкрди рдЙрди рдбреЛрдореЗрди рдХреЛ рдкрдХрдбрд╝рддрд╛ рд╣реИ рдЬреЛ рдореМрдЬреВрдж рдирд╣реАрдВ рд╣реИрдВ рдпрд╛ рдЙрдЪрд┐рдд рдИрдореЗрд▓ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдХреА рдХрдореА рд╣реИред
рддреАрд╕рд░реА рд▓реЗрдпрд░ SMTP рд╕рддреНрдпрд╛рдкрди рдХрд░рддреА рд╣реИ, рдкреНрд░рд╛рдкреНрддрдХрд░реНрддрд╛ рдХреЗ рдореЗрд▓ рд╕рд░реНрд╡рд░ рд╕реЗ рдХрдиреЗрдХреНрдЯ рдХрд░рдХреЗ рдпрд╣ рд╕рддреНрдпрд╛рдкрд┐рдд рдХрд░рддреА рд╣реИ рдХрд┐ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдореЗрд▓рдмреЙрдХреНрд╕ рдореМрдЬреВрдж рд╣реИред рдпрд╣ рдЙрдЪреНрдЪрддрдо рд╕рдЯреАрдХрддрд╛ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ рд▓реЗрдХрд┐рди рдмреНрд▓реЙрдХ рд╣реЛрдиреЗ рд╕реЗ рдмрдЪрдиреЗ рдХреЗ рд▓рд┐рдП рд╕рд╛рд╡рдзрд╛рдиреАрдкреВрд░реНрд╡рдХ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред
рд╕рд┐рдВрдХреНрд░реЛрдирд╕ рдмрдирд╛рдо рдПрд╕рд┐рдВрдХреНрд░реЛрдирд╕ рд╕рддреНрдпрд╛рдкрди
рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХреЛ рдлрд╝реЙрд░реНрдо рд╕рдмрдорд┐рд╢рди рдХреЗ рджреМрд░рд╛рди рд╕рд┐рдВрдХреНрд░реЛрдирд╕ рд╕рддреНрдпрд╛рдкрди рдФрд░ рд╕рдмрдорд┐рд╢рди рдХреЗ рдмрд╛рдж рдПрд╕рд┐рдВрдХреНрд░реЛрдирд╕ рд╕рддреНрдпрд╛рдкрди рдХреЗ рдмреАрдЪ рдирд┐рд░реНрдгрдп рд▓реЗрдирд╛ рдЪрд╛рд╣рд┐рдПред рдкреНрд░рддреНрдпреЗрдХ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреЗ рдЕрд▓рдЧ-рдЕрд▓рдЧ рдлрд╛рдпрджреЗ рдФрд░ рдЯреНрд░реЗрдб-рдСрдл рд╣реИрдВред
рд╕рд┐рдВрдХреНрд░реЛрдирд╕ рд╕рддреНрдпрд╛рдкрди рдпреВрдЬрд░реНрд╕ рдХреЛ рддрддреНрдХрд╛рд▓ рдлреАрдбрдмреИрдХ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ, рдЕрдорд╛рдиреНрдп рдкрддреЛрдВ рдХреЛ рдЖрдкрдХреЗ рд╕рд┐рд╕реНрдЯрдо рдореЗрдВ рдкреНрд░рд╡реЗрд╢ рдХрд░рдиреЗ рд╕реЗ рд░реЛрдХрддрд╛ рд╣реИред рд╣рд╛рд▓рд╛рдВрдХрд┐, SMTP рд╕рддреНрдпрд╛рдкрди рдореЗрдВ рдХрдИ рд╕реЗрдХрдВрдб рд▓рдЧ рд╕рдХрддреЗ рд╣реИрдВ, рдЬреЛ рд░рдЬрд┐рд╕реНрдЯреНрд░реЗрд╢рди рдХреЗ рджреМрд░рд╛рди рдпреВрдЬрд░реНрд╕ рдХреЛ рд╕рдВрднрд╛рд╡рд┐рдд рд░реВрдк рд╕реЗ рдирд┐рд░рд╛рд╢ рдХрд░ рд╕рдХрддрд╛ рд╣реИред
рдПрд╕рд┐рдВрдХреНрд░реЛрдирд╕ рд╕рддреНрдпрд╛рдкрди рдкрддреЛрдВ рдХреЛ рддреБрд░рдВрдд рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддрд╛ рд╣реИ рдФрд░ рдмреИрдХрдЧреНрд░рд╛рдЙрдВрдб рдореЗрдВ рдЙрдиреНрд╣реЗрдВ рдорд╛рдиреНрдп рдХрд░рддрд╛ рд╣реИред рдпрд╣ рдмреЗрд╣рддрд░ рдпреВрдЬрд░ рдЕрдиреБрднрд╡ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ рд▓реЗрдХрд┐рди рд╕рдмрдорд┐рд╢рди рдХреЗ рдмрд╛рдж рд╕рддреНрдпрд╛рдкрди рд╡рд┐рдлрд▓ рд╣реЛрдиреЗ рд╡рд╛рд▓реЗ рдкрддреЛрдВ рдХреЛ рд╕рдВрднрд╛рд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрддрд┐рд░рд┐рдХреНрдд рд▓реЙрдЬрд┐рдХ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред
рдХрдИ рдкреНрд░реЛрдбрдХреНрд╢рди рд╕рд┐рд╕реНрдЯрдо рдПрдХ рд╣рд╛рдЗрдмреНрд░рд┐рдб рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ, рдмреИрдХрдЧреНрд░рд╛рдЙрдВрдб рдкреНрд░реЛрд╕реЗрд╕рд┐рдВрдЧ рдХреЗ рд▓рд┐рдП SMTP рд╕рддреНрдпрд╛рдкрди рдХреЛ рд╕реНрдердЧрд┐рдд рдХрд░рддреЗ рд╣реБрдП рддреЗрдЬ рд╕рд┐рдВрдЯреИрдХреНрд╕ рдФрд░ DNS рд╕рддреНрдпрд╛рдкрди рдХреЛ рд╕рд┐рдВрдХреНрд░реЛрдирд╕ рд░реВрдк рд╕реЗ рдХрд░рддреЗ рд╣реИрдВред
рд╕рд┐рдВрдЯреИрдХреНрд╕ рд╕рддреНрдпрд╛рдкрди рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди
рд╕рд┐рдВрдЯреИрдХреНрд╕ рд╕рддреНрдпрд╛рдкрди рдИрдореЗрд▓ рд╕рддреНрдпрд╛рдкрди рдХреА рдиреАрдВрд╡ рд╣реИ, рдорд╣рдВрдЧреЗ рдиреЗрдЯрд╡рд░реНрдХ рдСрдкрд░реЗрд╢рди рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рд╡рд┐рдХреГрдд рдкрддреЛрдВ рдХреЛ рдкрдХрдбрд╝рддреА рд╣реИред
рдИрдореЗрд▓ рдкрддрд╛ рд╕рдВрд░рдЪрдирд╛ рдХреЛ рд╕рдордЭрдирд╛
рдорд╛рдиреНрдп рдИрдореЗрд▓ рдкрддреЛрдВ рдореЗрдВ рдПрдХ рд▓реЛрдХрд▓ рдкрд╛рд░реНрдЯ, @ рдкреНрд░рддреАрдХ рдФрд░ рдПрдХ рдбреЛрдореЗрди рдкрд╛рд░реНрдЯ рд╣реЛрддрд╛ рд╣реИред рдЬрдмрдХрд┐ рдкреВрд░реНрдг RFC рд╡рд┐рдирд┐рд░реНрджреЗрд╢ рдЬрдЯрд┐рд▓ рдлрд╝реЙрд░реНрдореЗрдЯ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ, рд╡реНрдпрд╛рд╡рд╣рд╛рд░рд┐рдХ рд╕рддреНрдпрд╛рдкрди рдХреЛ рдЖрдорддреМрд░ рдкрд░ рд╕реНрд╡реАрдХреГрдд рдкреИрдЯрд░реНрди рдкрд░ рдзреНрдпрд╛рди рдХреЗрдВрджреНрд░рд┐рдд рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред
рд▓реЛрдХрд▓ рдкрд╛рд░реНрдЯ рдореЗрдВ рдЕрд▓реНрдлрд╛рдиреНрдпреВрдореЗрд░рд┐рдХ рд╡рд░реНрдг, рдбреЙрдЯреНрд╕, рд╣рд╛рдЗрдлрд╝рди, рдЕрдВрдбрд░рд╕реНрдХреЛрд░ рдФрд░ рдкреНрд▓рд╕ рд╕рд╛рдЗрди рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВред рдбреЛрдореЗрди рдкрд╛рд░реНрдЯ рдПрдХ рдорд╛рдиреНрдп рдбреЛрдореЗрди рдирд╛рдо рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП рдЬрд┐рд╕рдореЗрдВ рдбреЛрдореЗрди рдФрд░ рдЯреЙрдк-рд▓реЗрд╡рд▓ рдбреЛрдореЗрди рдХреЛ рдЕрд▓рдЧ рдХрд░рдиреЗ рд╡рд╛рд▓реА рдХрдо рд╕реЗ рдХрдо рдПрдХ рдбреЙрдЯ рд╣реЛред
рд░реЗрдЧреЗрдХреНрд╕-рдЖрдзрд╛рд░рд┐рдд рд╕рддреНрдпрд╛рдкрди
рд░реЗрдЧреБрд▓рд░ рдПрдХреНрд╕рдкреНрд░реЗрд╢рди рддреЗрдЬ, рд▓рдЪреАрд▓реА рдИрдореЗрд▓ рд╕рддреНрдпрд╛рдкрди рдкреНрд░рджрд╛рди рдХрд░рддреЗ рд╣реИрдВред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдПрдХ рд░реЗрдЧреЗрдХреНрд╕ рдмрдирд╛рдирд╛ рдЬреЛ рд╕рднреА рдорд╛рдиреНрдп рдкрддреЛрдВ рдХреЛ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдорд╛рдиреНрдп рдХрд░рддрд╛ рд╣реИ рдЬрдмрдХрд┐ рдЕрдорд╛рдиреНрдп рдкрддреЛрдВ рдХреЛ рдЕрд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддрд╛ рд╣реИ, рдЖрд╢реНрдЪрд░реНрдпрдЬрдирдХ рд░реВрдк рд╕реЗ рдЬрдЯрд┐рд▓ рд╣реИред
// Practical email validation regex for JavaScript
const emailRegex = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;
function validateEmailSyntax(email) {
if (!email || typeof email !== 'string') {
return { valid: false, error: 'Email is required' };
}
const trimmedEmail = email.trim().toLowerCase();
if (trimmedEmail.length > 254) {
return { valid: false, error: 'Email address too long' };
}
if (!emailRegex.test(trimmedEmail)) {
return { valid: false, error: 'Invalid email format' };
}
const [localPart, domain] = trimmedEmail.split('@');
if (localPart.length > 64) {
return { valid: false, error: 'Local part too long' };
}
return { valid: true, email: trimmedEmail };
}
рдмреЗрд╕рд┐рдХ рд░реЗрдЧреЗрдХреНрд╕ рд╕рддреНрдпрд╛рдкрди рд╕реЗ рдкрд░реЗ
рдЬрдмрдХрд┐ рд░реЗрдЧреЗрдХреНрд╕ рд╕реНрдкрд╖реНрдЯ рдлрд╝реЙрд░реНрдореЗрдЯрд┐рдВрдЧ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рдкрдХрдбрд╝рддрд╛ рд╣реИ, рдЕрддрд┐рд░рд┐рдХреНрдд рдЬрд╛рдВрдЪ рд╕рддреНрдпрд╛рдкрди рд╕рдЯреАрдХрддрд╛ рдореЗрдВ рд╕реБрдзрд╛рд░ рдХрд░рддреА рд╣реИред рдЗрдирдореЗрдВ рд▓рдЧрд╛рддрд╛рд░ рдбреЙрдЯреНрд╕ рдХреА рдЬрд╛рдВрдЪ рдХрд░рдирд╛, рдЯреЙрдк-рд▓реЗрд╡рд▓ рдбреЛрдореЗрди рд▓рдВрдмрд╛рдИ рдХреЛ рдорд╛рдиреНрдп рдХрд░рдирд╛, рдФрд░ рд╕рд╛рдорд╛рдиреНрдп рдЯрд╛рдЗрдкреЛ рдкреИрдЯрд░реНрди рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдирд╛ рд╢рд╛рдорд┐рд▓ рд╣реИред
function enhancedSyntaxValidation(email) {
const basicResult = validateEmailSyntax(email);
if (!basicResult.valid) return basicResult;
const normalizedEmail = basicResult.email;
const [localPart, domain] = normalizedEmail.split('@');
// Check for consecutive dots
if (localPart.includes('..') || domain.includes('..')) {
return { valid: false, error: 'Consecutive dots not allowed' };
}
// Check for leading/trailing dots
if (localPart.startsWith('.') || localPart.endsWith('.')) {
return { valid: false, error: 'Local part cannot start or end with dot' };
}
// Validate TLD
const tld = domain.split('.').pop();
if (tld.length < 2 || tld.length > 63) {
return { valid: false, error: 'Invalid top-level domain' };
}
// Check for numeric-only TLD (not valid)
if (/^\d+$/.test(tld)) {
return { valid: false, error: 'TLD cannot be numeric only' };
}
return { valid: true, email: normalizedEmail };
}
DNS рдФрд░ MX рд░рд┐рдХреЙрд░реНрдб рд╕рддреНрдпрд╛рдкрди
рд╕рд┐рдВрдЯреИрдХреНрд╕ рд╕рддреНрдпрд╛рдкрди рдХреЗ рдмрд╛рдж, DNS рд╕рддреНрдпрд╛рдкрди рдорд╛рдиреНрдп MX рд░рд┐рдХреЙрд░реНрдб рдХреА рдЬрд╛рдВрдЪ рдХрд░рдХреЗ рдпрд╣ рд╕рддреНрдпрд╛рдкрд┐рдд рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдИрдореЗрд▓ рдбреЛрдореЗрди рдореЗрд▓ рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддрд╛ рд╣реИред
MX рд░рд┐рдХреЙрд░реНрдб рдХреЛ рд╕рдордЭрдирд╛
Mail Exchange (MX) рд░рд┐рдХреЙрд░реНрдб DNS рд░рд┐рдХреЙрд░реНрдб рд╣реИрдВ рдЬреЛ рдХрд┐рд╕реА рдбреЛрдореЗрди рдХреЗ рд▓рд┐рдП рдИрдореЗрд▓ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЬрд┐рдореНрдореЗрджрд╛рд░ рдореЗрд▓ рд╕рд░реНрд╡рд░реЛрдВ рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рддреЗ рд╣реИрдВред рдкреНрд░рддреНрдпреЗрдХ MX рд░рд┐рдХреЙрд░реНрдб рдореЗрдВ рдПрдХ рдкреНрд░рд╛рдердорд┐рдХрддрд╛ рдорд╛рди рдФрд░ рдПрдХ рд╣реЛрд╕реНрдЯрдирд╛рдо рд╢рд╛рдорд┐рд▓ рд╣реЛрддрд╛ рд╣реИ, рдЬрд┐рд╕рд╕реЗ рдбреЛрдореЗрди рдлреЗрд▓рдУрд╡рд░ рдХреЗ рд╕рд╛рде рдХрдИ рдореЗрд▓ рд╕рд░реНрд╡рд░реЛрдВ рдХреЛ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
user@example.com рдХреЛ рдИрдореЗрд▓ рднреЗрдЬрддреЗ рд╕рдордп, рднреЗрдЬрдиреЗ рд╡рд╛рд▓рд╛ рд╕рд░реНрд╡рд░ example.com рдХреЗ MX рд░рд┐рдХреЙрд░реНрдб рдХреЗ рд▓рд┐рдП DNS рдХреЛ рдХреНрд╡реЗрд░реА рдХрд░рддрд╛ рд╣реИ, рдлрд┐рд░ рдЙрдЪреНрдЪрддрдо рдкреНрд░рд╛рдердорд┐рдХрддрд╛ (рд╕рдмрд╕реЗ рдХрдо рд╕рдВрдЦреНрдпрд╛) рдореЗрд▓ рд╕рд░реНрд╡рд░ рд╕реЗ рдХрдиреЗрдХреНрдЯ рд╣реЛрддрд╛ рд╣реИ рдЬреЛ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рджреЗрддрд╛ рд╣реИред
Node.js рдореЗрдВ MX рд▓реБрдХрдЕрдк рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди
Node.js dns рдореЙрдбреНрдпреВрд▓ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдмрд┐рд▓реНрдЯ-рдЗрди DNS рд░рд┐рдЬрд╝реЛрд▓реНрдпреВрд╢рди рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ, рдЬрд┐рд╕рд╕реЗ MX рд╕рддреНрдпрд╛рдкрди рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рд╕рд░рд▓ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред
const dns = require('dns').promises;
async function validateMXRecords(domain) {
try {
const mxRecords = await dns.resolveMx(domain);
if (!mxRecords || mxRecords.length === 0) {
return {
valid: false,
error: 'No MX records found',
domain
};
}
// Sort by priority (lower is higher priority)
const sortedRecords = mxRecords.sort((a, b) => a.priority - b.priority);
return {
valid: true,
domain,
mxRecords: sortedRecords,
primaryMX: sortedRecords[0].exchange
};
} catch (error) {
if (error.code === 'ENOTFOUND' || error.code === 'ENODATA') {
return {
valid: false,
error: 'Domain does not exist or has no MX records',
domain
};
}
return {
valid: false,
error: `DNS lookup failed: ${error.message}`,
domain
};
}
}
async function validateEmailDomain(email) {
const domain = email.split('@')[1];
// First try MX records
const mxResult = await validateMXRecords(domain);
if (mxResult.valid) return mxResult;
// Fall back to A record check (some domains accept mail without MX)
try {
const aRecords = await dns.resolve4(domain);
if (aRecords && aRecords.length > 0) {
return {
valid: true,
domain,
mxRecords: [],
fallbackToA: true,
aRecords
};
}
} catch (error) {
// A record lookup also failed
}
return mxResult;
}
DNS рдПрдЬ рдХреЗрд╕реЗрд╕ рдХреЛ рд╕рдВрднрд╛рд▓рдирд╛
рдкреНрд░реЛрдбрдХреНрд╢рди рдИрдореЗрд▓ рд╕рддреНрдпрд╛рдкрди рдХреЛ рдЯрд╛рдЗрдордЖрдЙрдЯ, рдЕрд╕реНрдерд╛рдпреА рд╡рд┐рдлрд▓рддрд╛рдУрдВ рдФрд░ рдЕрд╕рд╛рдорд╛рдиреНрдп рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рд╡рд╛рд▓реЗ рдбреЛрдореЗрди рд╕рд╣рд┐рдд рд╡рд┐рднрд┐рдиреНрди DNS рдПрдЬ рдХреЗрд╕реЗрд╕ рдХреЛ рд╕рдВрднрд╛рд▓рдирд╛ рдЪрд╛рд╣рд┐рдПред
async function robustDNSValidation(email, options = {}) {
const { timeout = 5000, retries = 2 } = options;
const domain = email.split('@')[1];
for (let attempt = 0; attempt <= retries; attempt++) {
try {
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), timeout);
const result = await validateEmailDomain(email);
clearTimeout(timeoutId);
return result;
} catch (error) {
if (attempt === retries) {
return {
valid: false,
error: 'DNS validation failed after retries',
domain,
temporary: true
};
}
// Exponential backoff
await new Promise(resolve =>
setTimeout(resolve, Math.pow(2, attempt) * 100)
);
}
}
}
SMTP рд╕рддреНрдпрд╛рдкрди рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди
SMTP рд╕рддреНрдпрд╛рдкрди рдкреНрд░рд╛рдкреНрддрдХрд░реНрддрд╛ рдХреЗ рдореЗрд▓ рд╕рд░реНрд╡рд░ рд╕реЗ рд╕реАрдзреЗ рдХреНрд╡реЗрд░реА рдХрд░рдХреЗ рдпрд╣ рд╕рддреНрдпрд╛рдкрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдЪреНрдЪрддрдо рд╕рдЯреАрдХрддрд╛ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдореЗрд▓рдмреЙрдХреНрд╕ рдореМрдЬреВрдж рд╣реИред
SMTP рд╕рддреНрдпрд╛рдкрди рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ
SMTP рд╕рддреНрдпрд╛рдкрди рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рд╕рдВрджреЗрд╢ рд╡рд┐рддрд░рд┐рдд рдХрд┐рдП рдмрд┐рдирд╛ рдИрдореЗрд▓ рднреЗрдЬрдиреЗ рдХреЗ рдкреНрд░рд╛рд░рдВрднрд┐рдХ рдЪрд░рдгреЛрдВ рдХрд╛ рдЕрдиреБрдХрд░рдг рдХрд░рддрд╛ рд╣реИред рд╕рддреНрдпрд╛рдкрди рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореЗрд▓ рд╕рд░реНрд╡рд░ рд╕реЗ рдХрдиреЗрдХреНрд╢рди рд╕реНрдерд╛рдкрд┐рдд рдХрд░рддреА рд╣реИ, EHLO/HELO рдХреЗ рд╕рд╛рде рдЦреБрдж рдХреЛ рдкреЗрд╢ рдХрд░рддреА рд╣реИ, MAIL FROM рдХреЗ рд╕рд╛рде рд╕реЗрдВрдбрд░ рдкрддрд╛ рдкреНрд░рджрд╛рди рдХрд░рддреА рд╣реИ, рдлрд┐рд░ RCPT TO рдХреЗ рд╕рд╛рде рд▓рдХреНрд╖реНрдп рдкрддреЗ рдкрд░ рднреЗрдЬрдиреЗ рдХрд╛ рдЕрдиреБрд░реЛрдз рдХрд░рддреА рд╣реИред
RCPT TO рдХреЗ рд▓рд┐рдП рдореЗрд▓ рд╕рд░реНрд╡рд░ рдХреА рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдЗрдВрдЧрд┐рдд рдХрд░рддреА рд╣реИ рдХрд┐ рдореЗрд▓рдмреЙрдХреНрд╕ рдореМрдЬреВрдж рд╣реИ рдпрд╛ рдирд╣реАрдВред рдПрдХ 250 рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдкреБрд╖реНрдЯрд┐ рдХрд░рддреА рд╣реИ рдХрд┐ рдкрддрд╛ рдорд╛рдиреНрдп рд╣реИ, рдЬрдмрдХрд┐ 550 рдЗрдВрдЧрд┐рдд рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдпреВрдЬрд░ рдореМрдЬреВрдж рдирд╣реАрдВ рд╣реИред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдХрдИ рд╕рд░реНрд╡рд░ рдЕрдм рдХреИрдЪ-рдСрд▓ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдпрд╛ рдЧреНрд░реЗрд▓рд┐рд╕реНрдЯрд┐рдВрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ рдЬреЛ рдЗрд╕ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рдЬрдЯрд┐рд▓ рдмрдирд╛рддреЗ рд╣реИрдВред
Node.js рдореЗрдВ рдмреЗрд╕рд┐рдХ SMTP рд╕рддреНрдпрд╛рдкрди
const net = require('net');
class SMTPVerifier {
constructor(options = {}) {
this.timeout = options.timeout || 10000;
this.fromEmail = options.fromEmail || 'verify@example.com';
this.fromDomain = options.fromDomain || 'example.com';
}
async verify(email, mxHost) {
return new Promise((resolve) => {
const socket = new net.Socket();
let step = 0;
let response = '';
const cleanup = () => {
socket.destroy();
};
socket.setTimeout(this.timeout);
socket.on('timeout', () => {
cleanup();
resolve({ valid: false, error: 'Connection timeout' });
});
socket.on('error', (error) => {
cleanup();
resolve({ valid: false, error: error.message });
});
socket.on('data', (data) => {
response = data.toString();
const code = parseInt(response.substring(0, 3));
switch (step) {
case 0: // Connected, received greeting
if (code === 220) {
socket.write(`EHLO ${this.fromDomain}\r\n`);
step = 1;
} else {
cleanup();
resolve({ valid: false, error: 'Invalid greeting' });
}
break;
case 1: // EHLO response
if (code === 250) {
socket.write(`MAIL FROM:<${this.fromEmail}>\r\n`);
step = 2;
} else {
cleanup();
resolve({ valid: false, error: 'EHLO rejected' });
}
break;
case 2: // MAIL FROM response
if (code === 250) {
socket.write(`RCPT TO:<${email}>\r\n`);
step = 3;
} else {
cleanup();
resolve({ valid: false, error: 'MAIL FROM rejected' });
}
break;
case 3: // RCPT TO response - the verification result
socket.write('QUIT\r\n');
cleanup();
if (code === 250) {
resolve({ valid: true, email });
} else if (code === 550 || code === 551 || code === 552 || code === 553) {
resolve({ valid: false, error: 'Mailbox does not exist', code });
} else if (code === 450 || code === 451 || code === 452) {
resolve({ valid: false, error: 'Temporary failure', temporary: true, code });
} else {
resolve({ valid: false, error: `Unknown response: ${code}`, code });
}
break;
}
});
socket.connect(25, mxHost);
});
}
}
SMTP рдЪреБрдиреМрддрд┐рдпреЛрдВ рдХреЛ рд╕рдВрднрд╛рд▓рдирд╛
рд╡рд╛рд╕реНрддрд╡рд┐рдХ рджреБрдирд┐рдпрд╛ рдХрд╛ SMTP рд╕рддреНрдпрд╛рдкрди рдЧреНрд░реЗрд▓рд┐рд╕реНрдЯрд┐рдВрдЧ, рд░реЗрдЯ рд▓рд┐рдорд┐рдЯрд┐рдВрдЧ рдФрд░ рдХреИрдЪ-рдСрд▓ рдбреЛрдореЗрди рд╕рд╣рд┐рдд рдХрдИ рдЪреБрдиреМрддрд┐рдпреЛрдВ рдХрд╛ рд╕рд╛рдордирд╛ рдХрд░рддрд╛ рд╣реИред рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХреЛ рдЗрди рд╕реНрдерд┐рддрд┐рдпреЛрдВ рдХреЛ рд╕рдВрднрд╛рд▓рдиреЗ рдХреЗ рд▓рд┐рдП рд░рдгрдиреАрддрд┐рдпреЛрдВ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред
async function comprehensiveSMTPVerification(email, mxRecords) {
const verifier = new SMTPVerifier({
fromEmail: 'verify@yourdomain.com',
fromDomain: 'yourdomain.com',
timeout: 15000
});
// Try each MX server in priority order
for (const mx of mxRecords) {
const result = await verifier.verify(email, mx.exchange);
// If we get a definitive answer, return it
if (result.valid || (!result.temporary && result.code === 550)) {
return result;
}
// For temporary failures or connection issues, try next server
if (result.temporary || result.error.includes('timeout')) {
continue;
}
// For other errors, return the result
return result;
}
return {
valid: false,
error: 'All MX servers failed',
temporary: true
};
}
рдИрдореЗрд▓ рд╕рддреНрдпрд╛рдкрди API рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛
рдЬрдмрдХрд┐ рдХрд╕реНрдЯрдо рд╕рддреНрдпрд╛рдкрди рдмрдирд╛рдирд╛ рд╢реИрдХреНрд╖рд┐рдХ рд╣реИ, рдкреНрд░реЛрдбрдХреНрд╢рди рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдЕрдХреНрд╕рд░ BillionVerify рдЬреИрд╕реЗ рдкреНрд░реЛрдлреЗрд╢рдирд▓ рдИрдореЗрд▓ рд╕рддреНрдпрд╛рдкрди API рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╕реЗ рд▓рд╛рднрд╛рдиреНрд╡рд┐рдд рд╣реЛрддреЗ рд╣реИрдВред
рдИрдореЗрд▓ рд╕рддреНрдпрд╛рдкрди API рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреНрдпреЛрдВ рдХрд░реЗрдВ
рдкреНрд░реЛрдлреЗрд╢рдирд▓ рдИрдореЗрд▓ рд╕рддреНрдпрд╛рдкрди рд╕реЗрд╡рд╛рдПрдВ рдХрд╕реНрдЯрдо рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдкрд░ рдХрдИ рдлрд╛рдпрджреЗ рдкреНрд░рджрд╛рди рдХрд░рддреА рд╣реИрдВред рд╡реЗ рдЬреНрдЮрд╛рдд рдбрд┐рд╕реНрдкреЛрдЬреЗрдмрд▓ рдИрдореЗрд▓ рдкреНрд░рджрд╛рддрд╛рдУрдВ, рдХреИрдЪ-рдСрд▓ рдбреЛрдореЗрди рдФрд░ рд╕реНрдкреИрдо рдЯреНрд░реИрдк рдХреЗ рд╡реНрдпрд╛рдкрдХ рдбреЗрдЯрд╛рдмреЗрд╕ рдмрдирд╛рдП рд░рдЦрддреЗ рд╣реИрдВред рд╡реЗ рдмреНрд▓реЙрдХ рд╣реБрдП рдмрд┐рдирд╛ рдЙрдЪреНрдЪ-рд╡реЙрд▓реНрдпреВрдо SMTP рд╕рддреНрдпрд╛рдкрди рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рдмреБрдирд┐рдпрд╛рджреА рдврд╛рдВрдЪреЗ рдХрд╛ рднреА рдкреНрд░рдмрдВрдзрди рдХрд░рддреЗ рд╣реИрдВред рд╡рд┐рд╕реНрддреГрдд рдЬрд╛рдирдХрд╛рд░реА рдХреЗ рд▓рд┐рдП API Implementation Guide рдкрдврд╝реЗрдВред
BillionVerify рдХрд╛ рдИрдореЗрд▓ рд╕рддреНрдпрд╛рдкрди API рдПрдХ рд╕рд░рд▓ REST API рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╕рд┐рдВрдЯреИрдХреНрд╕ рдЪреЗрдХрд┐рдВрдЧ, DNS рд╕рддреНрдпрд╛рдкрди, SMTP рд╕рддреНрдпрд╛рдкрди, рдбрд┐рд╕реНрдкреЛрдЬреЗрдмрд▓ рдИрдореЗрд▓ рдбрд┐рдЯреЗрдХреНрд╢рди рдФрд░ рдбрд┐рд▓реАрд╡рд░реЗрдмрд┐рд▓рд┐рдЯреА рд╕реНрдХреЛрд░рд┐рдВрдЧ рд╕рд╣рд┐рдд рд╡реНрдпрд╛рдкрдХ рд╕рддреНрдпрд╛рдкрди рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИред
BillionVerify API рдХреЛ рдПрдХреАрдХреГрдд рдХрд░рдирд╛
const axios = require('axios');
class BillionVerifyClient {
constructor(apiKey) {
this.apiKey = apiKey;
this.baseURL = 'https://api.billionverify.com/v1';
}
async verifySingle(email) {
try {
const response = await axios.get(`${this.baseURL}/verify`, {
params: { email },
headers: {
'Authorization': `Bearer ${this.apiKey}`,
'Content-Type': 'application/json'
}
});
return {
success: true,
data: response.data
};
} catch (error) {
return {
success: false,
error: error.response?.data?.message || error.message
};
}
}
async verifyBatch(emails) {
try {
const response = await axios.post(`${this.baseURL}/verify/batch`, {
emails
}, {
headers: {
'Authorization': `Bearer ${this.apiKey}`,
'Content-Type': 'application/json'
}
});
return {
success: true,
data: response.data
};
} catch (error) {
return {
success: false,
error: error.response?.data?.message || error.message
};
}
}
}
// Usage example
async function validateUserEmail(email) {
const client = new BillionVerifyClient(process.env.BILLIONVERIFY_API_KEY);
const result = await client.verifySingle(email);
if (!result.success) {
console.error('Verification failed:', result.error);
return { valid: false, error: 'Verification service unavailable' };
}
const { data } = result;
return {
valid: data.deliverable,
email: data.email,
status: data.status,
isDisposable: data.is_disposable,
isCatchAll: data.is_catch_all,
score: data.quality_score
};
}
рд╡реЗрдм рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдореЗрдВ рд╡рд╛рд╕реНрддрд╡рд┐рдХ-рд╕рдордп рд╕рддреНрдпрд╛рдкрди
рд╡реЗрдм рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдореЗрдВ рд╡рд╛рд╕реНрддрд╡рд┐рдХ-рд╕рдордп рдИрдореЗрд▓ рд╕рддреНрдпрд╛рдкрди рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдпреВрдЬрд░ рдЕрдиреБрднрд╡ рдФрд░ рдкреНрд░рджрд░реНрд╢рди рдкрд░ рд╕рд╛рд╡рдзрд╛рдиреАрдкреВрд░реНрд╡рдХ рд╡рд┐рдЪрд╛рд░ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред
рдлреНрд░рдВрдЯрдПрдВрдб рд╕рддреНрдпрд╛рдкрди рд░рдгрдиреАрддрд┐
рдлреНрд░рдВрдЯрдПрдВрдб рд╕рддреНрдпрд╛рдкрди рдХреЛ рд╕реНрдкрд╖реНрдЯ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЗ рд▓рд┐рдП рддрддреНрдХрд╛рд▓ рдлреАрдбрдмреИрдХ рдкреНрд░рджрд╛рди рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП рдЬрдмрдХрд┐ рд╡реНрдпрд╛рдкрдХ рд╕рддреНрдпрд╛рдкрди рдХреЛ рдмреИрдХрдПрдВрдб рдореЗрдВ рд╕реНрдердЧрд┐рдд рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред рдпрд╣ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдпреВрдЬрд░ рдЕрдиреБрднрд╡ рдХреЛ рд╕реБрд░рдХреНрд╖рд╛ рдХреЗ рд╕рд╛рде рд╕рдВрддреБрд▓рд┐рдд рдХрд░рддрд╛ рд╣реИред
// Frontend email validation with debouncing
class EmailValidator {
constructor(options = {}) {
this.debounceMs = options.debounceMs || 500;
this.onValidating = options.onValidating || (() => {});
this.onResult = options.onResult || (() => {});
this.pendingRequest = null;
this.debounceTimer = null;
}
validateSyntax(email) {
const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return regex.test(email);
}
async validate(email) {
// Clear any pending requests
if (this.debounceTimer) {
clearTimeout(this.debounceTimer);
}
// Immediate syntax check
if (!this.validateSyntax(email)) {
this.onResult({
valid: false,
error: 'Please enter a valid email address'
});
return;
}
// Debounce API calls
this.debounceTimer = setTimeout(async () => {
this.onValidating(true);
try {
const response = await fetch('/api/verify-email', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ email })
});
const result = await response.json();
this.onResult(result);
} catch (error) {
this.onResult({
valid: false,
error: 'Unable to verify email'
});
} finally {
this.onValidating(false);
}
}, this.debounceMs);
}
}
// React component example
function EmailInput() {
const [email, setEmail] = useState('');
const [status, setStatus] = useState({ checking: false, result: null });
const validator = useMemo(() => new EmailValidator({
onValidating: (checking) => setStatus(s => ({ ...s, checking })),
onResult: (result) => setStatus(s => ({ ...s, result }))
}), []);
const handleChange = (e) => {
const value = e.target.value;
setEmail(value);
if (value) validator.validate(value);
};
return (
<div className="email-input">
<input
type="email"
value={email}
onChange={handleChange}
placeholder="Enter your email"
/>
{status.checking && <span className="loading">Verifying...</span>}
{status.result && (
<span className={status.result.valid ? 'valid' : 'invalid'}>
{status.result.valid ? 'тЬУ Valid email' : status.result.error}
</span>
)}
</div>
);
}
рдмреИрдХрдПрдВрдб API рдПрдВрдбрдкреЙрдЗрдВрдЯ
рдмреИрдХрдПрдВрдб API рдПрдВрдбрдкреЙрдЗрдВрдЯ рдХреЛ рд░реЗрдЯ рд▓рд┐рдорд┐рдЯрд┐рдВрдЧ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рджреБрд░реБрдкрдпреЛрдЧ рд╕реЗ рд╕реБрд░рдХреНрд╖рд╛ рдХрд░рддреЗ рд╣реБрдП рд╡реНрдпрд╛рдкрдХ рд╕рддреНрдпрд╛рдкрди рд▓рд╛рдЧреВ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред
const express = require('express');
const rateLimit = require('express-rate-limit');
const app = express();
// Rate limiting for verification endpoint
const verifyLimiter = rateLimit({
windowMs: 60 * 1000, // 1 minute
max: 10, // 10 requests per minute per IP
message: { error: 'Too many verification requests' }
});
app.post('/api/verify-email', verifyLimiter, async (req, res) => {
const { email } = req.body;
if (!email) {
return res.status(400).json({ valid: false, error: 'Email required' });
}
try {
// Layer 1: Syntax validation
const syntaxResult = enhancedSyntaxValidation(email);
if (!syntaxResult.valid) {
return res.json(syntaxResult);
}
// Layer 2: DNS validation
const dnsResult = await robustDNSValidation(syntaxResult.email);
if (!dnsResult.valid) {
return res.json(dnsResult);
}
// Layer 3: API-based comprehensive validation
const apiResult = await validateUserEmail(syntaxResult.email);
res.json(apiResult);
} catch (error) {
console.error('Verification error:', error);
res.status(500).json({ valid: false, error: 'Verification failed' });
}
});
рдбрд┐рд╕реНрдкреЛрдЬреЗрдмрд▓ рдФрд░ рдЕрд╕реНрдерд╛рдпреА рдИрдореЗрд▓ рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдирд╛
рдбрд┐рд╕реНрдкреЛрдЬреЗрдмрд▓ рдИрдореЗрд▓ рдкрддреЗ рдЙрди рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЗ рд▓рд┐рдП рдорд╣рддреНрд╡рдкреВрд░реНрдг рдЪреБрдиреМрддрд┐рдпрд╛рдВ рдкреЗрд╢ рдХрд░рддреЗ рд╣реИрдВ рдЬрд┐рдиреНрд╣реЗрдВ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдпреВрдЬрд░ рдЬреБрдбрд╝рд╛рд╡ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рдЗрди рдкрддреЛрдВ рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдирд╛ рдФрд░ рдмреНрд▓реЙрдХ рдХрд░рдирд╛ рд╕реВрдЪреА рдЧреБрдгрд╡рддреНрддрд╛ рдмрдирд╛рдП рд░рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рд╣реИред
рдбрд┐рд╕реНрдкреЛрдЬреЗрдмрд▓ рдИрдореЗрд▓ рдХреЛ рд╕рдордЭрдирд╛
Guerrilla Mail, 10MinuteMail рдФрд░ Mailinator рдЬреИрд╕реА рдбрд┐рд╕реНрдкреЛрдЬреЗрдмрд▓ рдИрдореЗрд▓ рд╕реЗрд╡рд╛рдПрдВ рдЕрд╕реНрдерд╛рдпреА рдкрддреЗ рдкреНрд░рджрд╛рди рдХрд░рддреА рд╣реИрдВ рдЬрд┐рдиреНрд╣реЗрдВ рдпреВрдЬрд░реНрд╕ рдмрд┐рдирд╛ рд░рдЬрд┐рд╕реНрдЯреНрд░реЗрд╢рди рдХреЗ рддреБрд░рдВрдд рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВред рдЬрдмрдХрд┐ рдЗрди рд╕реЗрд╡рд╛рдУрдВ рдХреЗ рд╡реИрдз рдЙрдкрдпреЛрдЧ рд╣реИрдВ, рд╡реЗ рдЕрдХреНрд╕рд░ рд░рдЬрд┐рд╕реНрдЯреНрд░реЗрд╢рди рдЖрд╡рд╢реНрдпрдХрддрд╛рдУрдВ рдХреЛ рдмрд╛рдпрдкрд╛рд╕ рдХрд░рдиреЗ рдпрд╛ рдирдХрд▓реА рдЦрд╛рддреЗ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХреА рдЬрд╛рддреА рд╣реИрдВред
рдбрд┐рд╕реНрдкреЛрдЬреЗрдмрд▓ рдИрдореЗрд▓ рдбрд┐рдЯреЗрдХреНрдЯрд░ рдмрдирд╛рдирд╛
class DisposableEmailDetector {
constructor() {
// Common disposable email domains
this.knownDisposable = new Set([
'guerrillamail.com', 'guerrillamail.org',
'10minutemail.com', '10minutemail.net',
'mailinator.com', 'mailinator.net',
'tempmail.com', 'tempmail.net',
'throwaway.email', 'throwawaymail.com',
'fakeinbox.com', 'trashmail.com',
'getnada.com', 'temp-mail.org',
'mohmal.com', 'emailondeck.com'
// Add more known disposable domains
]);
// Patterns that often indicate disposable services
this.suspiciousPatterns = [
/^temp/i,
/^trash/i,
/^throw/i,
/^fake/i,
/^disposable/i,
/\d{2,}mail/i,
/minutemail/i
];
}
isDisposable(email) {
const domain = email.split('@')[1].toLowerCase();
// Check known disposable domains
if (this.knownDisposable.has(domain)) {
return { isDisposable: true, reason: 'Known disposable domain' };
}
// Check suspicious patterns
for (const pattern of this.suspiciousPatterns) {
if (pattern.test(domain)) {
return { isDisposable: true, reason: 'Suspicious domain pattern' };
}
}
return { isDisposable: false };
}
async updateDisposableList() {
// Fetch updated list from a maintained source
try {
const response = await fetch(
'https://raw.githubusercontent.com/disposable-email-domains/disposable-email-domains/master/disposable_email_blocklist.conf'
);
const text = await response.text();
const domains = text.split('\n').filter(d => d.trim());
domains.forEach(domain => this.knownDisposable.add(domain.toLowerCase()));
return { success: true, count: this.knownDisposable.size };
} catch (error) {
return { success: false, error: error.message };
}
}
}
рдкреНрд░рджрд░реНрд╢рди рдЕрдиреБрдХреВрд▓рди рд░рдгрдиреАрддрд┐рдпрд╛рдБ
рдпрджрд┐ рд╕рд╛рд╡рдзрд╛рдиреАрдкреВрд░реНрд╡рдХ рд▓рд╛рдЧреВ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рддреЛ рдИрдореЗрд▓ рд╕рддреНрдпрд╛рдкрди рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдкреНрд░рджрд░реНрд╢рди рдХреЛ рдкреНрд░рднрд╛рд╡рд┐рдд рдХрд░ рд╕рдХрддрд╛ рд╣реИред рдпреЗ рдЕрдиреБрдХреВрд▓рди рд░рдгрдиреАрддрд┐рдпрд╛рдБ рддреЗрдЬ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рд╕рдордп рдмрдирд╛рдП рд░рдЦрдиреЗ рдореЗрдВ рдорджрдж рдХрд░рддреА рд╣реИрдВред
рд╕рддреНрдпрд╛рдкрди рдкрд░рд┐рдгрд╛рдореЛрдВ рдХреЛ рдХреИрд╢ рдХрд░рдирд╛
рдХреИрд╢рд┐рдВрдЧ рдЕрдирд╛рд╡рд╢реНрдпрдХ рд╕рддреНрдпрд╛рдкрди рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЛ рдХрдо рдХрд░рддреА рд╣реИ рдФрд░ рдмрд╛рд░-рдмрд╛рд░ рд╕рддреНрдпрд╛рдкрди рдХреЗ рд▓рд┐рдП рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рд╕рдордп рдореЗрдВ рд╕реБрдзрд╛рд░ рдХрд░рддреА рд╣реИред
const NodeCache = require('node-cache');
class CachedEmailVerifier {
constructor(options = {}) {
this.cache = new NodeCache({
stdTTL: options.ttl || 3600, // 1 hour default
checkperiod: options.checkperiod || 600
});
this.verifier = options.verifier;
}
async verify(email) {
const normalizedEmail = email.toLowerCase().trim();
const cacheKey = `email:${normalizedEmail}`;
// Check cache first
const cached = this.cache.get(cacheKey);
if (cached) {
return { ...cached, fromCache: true };
}
// Perform verification
const result = await this.verifier.verify(normalizedEmail);
// Cache the result (don't cache temporary failures)
if (!result.temporary) {
this.cache.set(cacheKey, result);
}
return result;
}
invalidate(email) {
const normalizedEmail = email.toLowerCase().trim();
this.cache.del(`email:${normalizedEmail}`);
}
getStats() {
return this.cache.getStats();
}
}
рд░рд┐рдХреНрд╡реЗрд╕реНрдЯ рдХреНрдпреВрдЗрдВрдЧ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдирд╛
рдЙрдЪреНрдЪ-рд╡реЙрд▓реНрдпреВрдо рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЗ рд▓рд┐рдП, рд░рд┐рдХреНрд╡реЗрд╕реНрдЯ рдХреНрдпреВрдЗрдВрдЧ рд╕рддреНрдпрд╛рдкрди рд╕реЗрд╡рд╛рдУрдВ рдХреЛ рдЕрднрд┐рднреВрдд рдХрд░рдиреЗ рд╕реЗ рд░реЛрдХрддреА рд╣реИ рдФрд░ рдирд┐рд╖реНрдкрдХреНрд╖ рд╕рдВрд╕рд╛рдзрди рд╡рд┐рддрд░рдг рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рддреА рд╣реИред
const Queue = require('bull');
const verificationQueue = new Queue('email-verification', {
redis: { host: 'localhost', port: 6379 },
defaultJobOptions: {
attempts: 3,
backoff: {
type: 'exponential',
delay: 1000
}
}
});
// Process verification jobs
verificationQueue.process(async (job) => {
const { email, userId } = job.data;
const result = await comprehensiveEmailVerification(email);
// Store result in database
await updateUserEmailStatus(userId, result);
return result;
});
// Queue a verification request
async function queueEmailVerification(email, userId) {
const job = await verificationQueue.add({
email,
userId
}, {
priority: 1,
delay: 0
});
return job.id;
}
рддреНрд░реБрдЯрд┐ рд╣реИрдВрдбрд▓рд┐рдВрдЧ рдФрд░ рд▓реЙрдЧрд┐рдВрдЧ
рд╡рд┐рд╢реНрд╡рд╕рдиреАрдп рдИрдореЗрд▓ рд╕рддреНрдпрд╛рдкрди рд╕рд┐рд╕реНрдЯрдо рдмрдирд╛рдП рд░рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдордЬрдмреВрдд рддреНрд░реБрдЯрд┐ рд╣реИрдВрдбрд▓рд┐рдВрдЧ рдФрд░ рд╡реНрдпрд╛рдкрдХ рд▓реЙрдЧрд┐рдВрдЧ рдЖрд╡рд╢реНрдпрдХ рд╣реИред
рд╡реНрдпрд╛рдкрдХ рддреНрд░реБрдЯрд┐ рд╣реИрдВрдбрд▓рд┐рдВрдЧ рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди
class EmailVerificationError extends Error {
constructor(message, code, details = {}) {
super(message);
this.name = 'EmailVerificationError';
this.code = code;
this.details = details;
this.timestamp = new Date().toISOString();
}
}
async function safeEmailVerification(email) {
const startTime = Date.now();
try {
// Validate input
if (!email || typeof email !== 'string') {
throw new EmailVerificationError(
'Invalid email input',
'INVALID_INPUT',
{ received: typeof email }
);
}
const result = await comprehensiveEmailVerification(email);
// Log successful verification
logger.info('Email verification completed', {
email: maskEmail(email),
valid: result.valid,
duration: Date.now() - startTime
});
return result;
} catch (error) {
// Log error with context
logger.error('Email verification failed', {
email: maskEmail(email),
error: error.message,
code: error.code,
duration: Date.now() - startTime,
stack: error.stack
});
// Return safe error response
return {
valid: false,
error: 'Verification failed',
errorCode: error.code || 'UNKNOWN_ERROR',
temporary: true
};
}
}
function maskEmail(email) {
const [local, domain] = email.split('@');
const maskedLocal = local.charAt(0) + '***' + local.charAt(local.length - 1);
return `${maskedLocal}@${domain}`;
}
рд╕реБрд░рдХреНрд╖рд╛ рд╡рд┐рдЪрд╛рд░
рдИрдореЗрд▓ рд╕рддреНрдпрд╛рдкрди рд╕рд┐рд╕реНрдЯрдо рдХреЛ рджреБрд░реБрдкрдпреЛрдЧ рдХреЛ рд░реЛрдХрдиреЗ рдФрд░ рдпреВрдЬрд░ рдбреЗрдЯрд╛ рдХреА рд░рдХреНрд╖рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реБрд░рдХреНрд╖рд╛ рдХреЛ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрддреЗ рд╣реБрдП рдбрд┐рдЬрд╝рд╛рдЗрди рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред
рдПрдиреНрдпреВрдорд░реЗрд╢рди рд╣рдорд▓реЛрдВ рдХреЛ рд░реЛрдХрдирд╛
рд╣рдорд▓рд╛рд╡рд░ рдорд╛рдиреНрдп рдИрдореЗрд▓ рдкрддреЛрдВ рдХреЛ рдЧрд┐рдирдиреЗ рдХреЗ рд▓рд┐рдП рдИрдореЗрд▓ рд╕рддреНрдпрд╛рдкрди рдПрдВрдбрдкреЙрдЗрдВрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдЗрд╕ рд╣рдорд▓реЗ рдХреЗ рд╡реЗрдХреНрдЯрд░ рдХреЗ рдЦрд┐рд▓рд╛рдл рд░рдХреНрд╖рд╛ рд▓рд╛рдЧреВ рдХрд░реЗрдВред
const crypto = require('crypto');
function secureVerificationResponse(result, options = {}) {
const { hideDetails = true } = options;
// Add consistent response timing to prevent timing attacks
const minResponseTime = 200;
const elapsed = Date.now() - result.startTime;
const delay = Math.max(0, minResponseTime - elapsed);
return new Promise(resolve => {
setTimeout(() => {
if (hideDetails && !result.valid) {
// Don't reveal whether email exists or domain is invalid
resolve({
valid: false,
message: 'Unable to verify email address'
});
} else {
resolve(result);
}
}, delay);
});
}
рд░реЗрдЯ рд▓рд┐рдорд┐рдЯрд┐рдВрдЧ рдФрд░ рджреБрд░реБрдкрдпреЛрдЧ рд░реЛрдХрдерд╛рдо
рд╕рддреНрдпрд╛рдкрди рдПрдВрдбрдкреЙрдЗрдВрдЯ рдХреЗ рджреБрд░реБрдкрдпреЛрдЧ рдХреЛ рд░реЛрдХрдиреЗ рдХреЗ рд▓рд┐рдП рд╡реНрдпрд╛рдкрдХ рд░реЗрдЯ рд▓рд┐рдорд┐рдЯрд┐рдВрдЧ рд▓рд╛рдЧреВ рдХрд░реЗрдВред
const rateLimit = require('express-rate-limit');
const RedisStore = require('rate-limit-redis');
const verificationRateLimiter = rateLimit({
store: new RedisStore({
client: redisClient,
prefix: 'rl:verify:'
}),
windowMs: 60 * 1000, // 1 minute
max: 5, // 5 requests per minute
keyGenerator: (req) => {
// Combine IP and user ID if authenticated
const userId = req.user?.id || 'anonymous';
return `${req.ip}:${userId}`;
},
handler: (req, res) => {
res.status(429).json({
error: 'Too many verification requests',
retryAfter: Math.ceil(req.rateLimit.resetTime / 1000)
});
}
});
рдИрдореЗрд▓ рд╕рддреНрдпрд╛рдкрди рд╕рд┐рд╕реНрдЯрдо рдХрд╛ рдкрд░реАрдХреНрд╖рдг
рд╡реНрдпрд╛рдкрдХ рдкрд░реАрдХреНрд╖рдг рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдИрдореЗрд▓ рд╕рддреНрдпрд╛рдкрди рд╕рд┐рд╕реНрдЯрдо рд╕рднреА рдкрд░рд┐рджреГрд╢реНрдпреЛрдВ рдореЗрдВ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВред
рд╕рддреНрдпрд╛рдкрди рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдпреВрдирд┐рдЯ рдкрд░реАрдХреНрд╖рдг
const { expect } = require('chai');
describe('Email Syntax Validation', () => {
it('should accept valid email addresses', () => {
const validEmails = [
'user@example.com',
'user.name@example.com',
'user+tag@example.com',
'user@subdomain.example.com'
];
validEmails.forEach(email => {
const result = validateEmailSyntax(email);
expect(result.valid).to.be.true;
});
});
it('should reject invalid email addresses', () => {
const invalidEmails = [
'invalid',
'@example.com',
'user@',
'user@@example.com',
'user@example',
'user@.com'
];
invalidEmails.forEach(email => {
const result = validateEmailSyntax(email);
expect(result.valid).to.be.false;
});
});
it('should handle edge cases', () => {
expect(validateEmailSyntax('')).to.have.property('valid', false);
expect(validateEmailSyntax(null)).to.have.property('valid', false);
expect(validateEmailSyntax(undefined)).to.have.property('valid', false);
});
});
рдирд┐рд╖реНрдХрд░реНрд╖
рдПрдХ рдбреЗрд╡рд▓рдкрд░ рдХреЗ рд░реВрдк рдореЗрдВ рдИрдореЗрд▓ рд╕рддреНрдпрд╛рдкрди рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдореВрд▓ рд╕рд┐рдВрдЯреИрдХреНрд╕ рдЪреЗрдХрд┐рдВрдЧ рд╕реЗ рдЙрдиреНрдирдд SMTP рд╕рддреНрдпрд╛рдкрди рддрдХ рдХрдИ рд╕рддреНрдпрд╛рдкрди рд▓реЗрдпрд░ рдХреЛ рд╕рдордЭрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рд╕реНрдерд╛рдиреАрдп рд╕рддреНрдпрд╛рдкрди, DNS рд▓реБрдХрдЕрдк рдФрд░ BillionVerify рдЬреИрд╕реЗ рдкреНрд░реЛрдлреЗрд╢рдирд▓ рд╕рддреНрдпрд╛рдкрди API рдХреЛ рд╕рдВрдпреЛрдЬрд┐рдд рдХрд░рдХреЗ, рдбреЗрд╡рд▓рдкрд░реНрд╕ рдордЬрдмреВрдд рд╕рд┐рд╕реНрдЯрдо рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ рдЬреЛ рдЙрддреНрдХреГрд╖реНрдЯ рдпреВрдЬрд░ рдЕрдиреБрднрд╡ рдкреНрд░рджрд╛рди рдХрд░рддреЗ рд╣реБрдП рдЙрдЪреНрдЪ рдбреЗрдЯрд╛ рдЧреБрдгрд╡рддреНрддрд╛ рдмрдирд╛рдП рд░рдЦрддреЗ рд╣реИрдВред рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА рдХреЗ рд▓рд┐рдП API Integration Guide рджреЗрдЦреЗрдВред
рд╕рдлрд▓ рдИрдореЗрд▓ рд╕рддреНрдпрд╛рдкрди рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рд▓рд┐рдП рдореБрдЦреНрдп рд╕рд┐рджреНрдзрд╛рдВрддреЛрдВ рдореЗрдВ рд╡реНрдпрд╛рдкрдХ рдХрд╡рд░реЗрдЬ рдХреЗ рд▓рд┐рдП рдХрдИ рд╕рддреНрдпрд╛рдкрди рд▓реЗрдпрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛, рдкреНрд░рджрд░реНрд╢рди рдФрд░ рд╕реБрд░рдХреНрд╖рд╛ рдХреЗ рд▓рд┐рдП рдЙрдЪрд┐рдд рдХреИрд╢рд┐рдВрдЧ рдФрд░ рд░реЗрдЯ рд▓рд┐рдорд┐рдЯрд┐рдВрдЧ рд▓рд╛рдЧреВ рдХрд░рдирд╛, рдПрдЬ рдХреЗрд╕реЗрд╕ рдФрд░ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреЛ рд╕реБрдЪрд╛рд░реВ рд░реВрдк рд╕реЗ рд╕рдВрднрд╛рд▓рдирд╛, рдФрд░ рд╕рддреНрдпрд╛рдкрди рд╕рдЯреАрдХрддрд╛ рдХреА рдирд┐рд░рдВрддрд░ рдирд┐рдЧрд░рд╛рдиреА рдФрд░ рд╕реБрдзрд╛рд░ рд╢рд╛рдорд┐рд▓ рд╣реИред
рдЪрд╛рд╣реЗ рдЖрдк рдХрд╕реНрдЯрдо рд╕рддреНрдпрд╛рдкрди рд▓реЙрдЬрд┐рдХ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рдЪреБрдирддреЗ рд╣реИрдВ рдпрд╛ рдкреНрд░реЛрдлреЗрд╢рдирд▓ API рдХрд╛ рд▓рд╛рдн рдЙрдард╛рддреЗ рд╣реИрдВ, рдЗрд╕ рдЧрд╛рдЗрдб рдореЗрдВ рд╢рд╛рдорд┐рд▓ рддрдХрдиреАрдХреЗрдВ рдИрдореЗрд▓ рд╕рддреНрдпрд╛рдкрди рд╕рд┐рд╕реНрдЯрдо рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдиреАрдВрд╡ рдкреНрд░рджрд╛рди рдХрд░рддреА рд╣реИрдВ рдЬреЛ рдЖрдкрдХреЗ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдФрд░ рдпреВрдЬрд░реНрд╕ рдХреА рд░рдХреНрд╖рд╛ рдХрд░рддреЗ рд╣реИрдВ рдЬрдмрдХрд┐ deliverability рдФрд░ рдЬреБрдбрд╝рд╛рд╡ рдХреЗ рдЙрдЪреНрдЪрддрдо рдорд╛рдирдХреЛрдВ рдХреЛ рдмрдирд╛рдП рд░рдЦрддреЗ рд╣реИрдВред Node.js implementation рдХреЗ рд▓рд┐рдП, Node.js Tutorial рджреЗрдЦреЗрдВред
рдЖрдЬ рд╣реА BillionVerify рдХреЗ рдбреЗрд╡рд▓рдкрд░-рдЕрдиреБрдХреВрд▓ API рдХреЗ рд╕рд╛рде рдЕрдкрдиреЗ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдореЗрдВ рдИрдореЗрд▓ рд╕рддреНрдпрд╛рдкрди рд▓рд╛рдЧреВ рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░реЗрдВред рдореБрдлреНрдд рд╕рддреНрдпрд╛рдкрди рдХреНрд░реЗрдбрд┐рдЯ рдФрд░ рд╡реНрдпрд╛рдкрдХ рджрд╕реНрддрд╛рд╡реЗрдЬрд╝реАрдХрд░рдг рдХреЗ рд╕рд╛рде рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП BillionVerify рдкрд░ рд╕рд╛рдЗрди рдЕрдк рдХрд░реЗрдВред