truemail 1.7.0 → 1.9.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2019 Vladislav Trotsenko
3
+ Copyright (c) 2019-2020 Vladislav Trotsenko
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -1,9 +1,11 @@
1
- # <img src='https://repository-images.githubusercontent.com/173723932/6dffee00-e88e-11e9-94b6-c97aacc0df00' height='250' alt='Truemail - configurable framework agnostic plain Ruby email validator' />
1
+ ![Truemail - configurable framework agnostic plain Ruby email validator](https://truemail-rb.org/assets/images/truemail_logo.png)
2
2
 
3
3
  [![Maintainability](https://api.codeclimate.com/v1/badges/657aa241399927dcd2e2/maintainability)](https://codeclimate.com/github/rubygarage/truemail/maintainability) [![Test Coverage](https://api.codeclimate.com/v1/badges/657aa241399927dcd2e2/test_coverage)](https://codeclimate.com/github/rubygarage/truemail/test_coverage) [![CircleCI](https://circleci.com/gh/rubygarage/truemail/tree/master.svg?style=svg)](https://circleci.com/gh/rubygarage/truemail/tree/master) [![Gem Version](https://badge.fury.io/rb/truemail.svg)](https://badge.fury.io/rb/truemail) [![Downloads](https://img.shields.io/gem/dt/truemail.svg?colorA=004d99&colorB=0073e6)](https://rubygems.org/gems/truemail) [![Gitter](https://badges.gitter.im/truemail-rb/community.svg)](https://gitter.im/truemail-rb/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) [![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-v1.4%20adopted-ff69b4.svg)](CODE_OF_CONDUCT.md)
4
4
 
5
5
  Configurable framework agnostic plain Ruby email validator. Verify email via Regex, DNS and SMTP. Be sure that email address valid and exists.
6
6
 
7
+ > Actual and maintainable documentation :books: for developers is living [here](https://truemail-rb.org/truemail-gem).
8
+
7
9
  ## Table of Contents
8
10
 
9
11
  - [Synopsis](#synopsis)
@@ -32,11 +34,16 @@ Configurable framework agnostic plain Ruby email validator. Verify email via Reg
32
34
  - [SMTP validation](#smtp-validation)
33
35
  - [SMTP safe check disabled](#smtp-safe-check-disabled)
34
36
  - [SMTP safe check enabled](#smtp-safe-check-enabled)
35
- - [Event logger](#event-logger)
36
- - [Available tracking events](#available-tracking-events)
37
- - [JSON serializer](#json-serializer)
38
37
  - [Host audit features](#host-audit-features)
38
+ - [IP audit](#ip-audit)
39
+ - [DNS audit](#dns-audit)
39
40
  - [PTR audit](#ptr-audit)
41
+ - [Example of using](#example-of-using)
42
+ - [Event logger](#event-logger)
43
+ - [Available tracking events](#available-tracking-events)
44
+ - [JSON serializers](#json-serializers)
45
+ - [Auditor JSON serializer](#auditor-json-serializer)
46
+ - [Validator JSON serializer](#validator-json-serializer)
40
47
  - [Truemail helpers](#truemail-helpers)
41
48
  - [.valid?](#valid)
42
49
  - [#as_json](#as_json)
@@ -48,11 +55,10 @@ Configurable framework agnostic plain Ruby email validator. Verify email via Reg
48
55
  - [Credits](#credits)
49
56
  - [Versioning](#versioning)
50
57
  - [Changelog](CHANGELOG.md)
51
- - [Wiki](https://github.com/rubygarage/truemail/wiki)
52
58
 
53
59
  ## Synopsis
54
60
 
55
- Email validation is a tricky thing. There are a number of different ways to validate an email address and all mechanisms must conform with the best practices and provide proper validation. You can get more information about email validation techniques in our [blog](https://rubygarage.org/blog/how-to-validate-emails). The Truemail gem helps you validate emails via regex pattern, presence of DNS records, and real existence of email account on a current email server.
61
+ Email validation is a tricky thing. There are a number of different ways to validate an email address and all mechanisms must conform with the best practices and provide proper validation. The Truemail gem helps you validate emails via regex pattern, presence of DNS records, and real existence of email account on a current email server.
56
62
 
57
63
  **Syntax Checking**: Checks the email addresses via regex pattern.
58
64
 
@@ -70,7 +76,8 @@ Also Truemail gem allows performing an audit of the host in which runs.
70
76
  - Whitelist/blacklist validation layers
71
77
  - Simple SMTP debugger
72
78
  - Event logger
73
- - JSON serializer
79
+ - Host auditor tools (helps to detect common host problems interfering to proper email verification)
80
+ - JSON serializers
74
81
 
75
82
  ## Requirements
76
83
 
@@ -892,76 +899,33 @@ Truemail.validate('email@example.com')
892
899
  @validation_type=:smtp>
893
900
  ```
894
901
 
895
- ### Event logger
896
-
897
- Truemail gem allows to output tracking events to stdout/file or both of these. Please note, at least one of the outputs must exist. Tracking event by default is `:error`
898
-
899
- ```ruby
900
- Truemail.configure do |config|
901
- config.logger = { tracking_event: :all, stdout: true, log_absolute_path: '/home/app/log/truemail.log' }
902
- end
903
- ```
904
-
905
- #### Available tracking events
906
-
907
- - `:all`, all detected events including success validation cases
908
- - `:unrecognized_error`, unrecognized errors only (when `smtp_safe_check = true` and SMTP server does not return an exact answer that the email does not exist)
909
- - `:recognized_error`, recognized errors only
910
- - `:error`, recognized and unrecognized errors only
902
+ ### Host audit features
911
903
 
912
- ### JSON serializer
904
+ Truemail gem allows performing an audit of the host in which runs. It will help to detect common host problems interfering to proper email verification.
913
905
 
914
- Truemail has built in JSON serializer for `Truemail::Validator` instance, so you can represent your email validation result as json.
906
+ #### IP audit
915
907
 
916
- ```ruby
917
- Truemail::Log::Serializer::Json.call(Truemail.validate('nonexistent_email@bestweb.com.ua'))
918
-
919
- =>
920
- # Serialized Truemail::Validator instance
921
- {
922
- "date": "2019-10-28 10:15:51 +0200",
923
- "email": "nonexistent_email@bestweb.com.ua",
924
- "validation_type": "smtp",
925
- "success": false,
926
- "errors": {
927
- "smtp": "smtp error"
928
- },
929
- "smtp_debug": [
930
- {
931
- "mail_host": "213.180.193.89",
932
- "port_opened": true,
933
- "connection": true,
934
- "errors": {
935
- "rcptto": "550 5.7.1 No such user!\n"
936
- }
937
- }
938
- ],
939
- "configuration": {
940
- "validation_type_by_domain": null,
941
- "whitelist_validation": false,
942
- "whitelisted_domains": null,
943
- "blacklisted_domains": null,
944
- "smtp_safe_check": false,
945
- "email_pattern": "default gem value",
946
- "smtp_error_body_pattern": "default gem value"
947
- }
948
- }
949
- ```
908
+ Checks is current Truemail host has proper internet connection and detects current host ip address.
950
909
 
951
- ### Host audit features
910
+ #### DNS audit
952
911
 
953
- Truemail gem allows performing an audit of the host in which runs. Only PTR record audit performs for today.
912
+ Checks is verifier domain refer to current Truemail host IP address.
954
913
 
955
914
  #### PTR audit
956
915
 
957
916
  So what is a PTR record? A PTR record, or pointer record, enables someone to perform a reverse DNS lookup. This allows them to determine your domain name based on your IP address. Because generic domain names without a PTR are often associated with spammers, incoming mail servers identify email from hosts without PTR records as spam and you can't verify yours emails qualitatively.
958
917
 
918
+ Checks is PTR record exists for your Truemail host ip address exists and refers to current verifier domain.
919
+
920
+ #### Example of using
921
+
959
922
  ```ruby
960
923
  Truemail.host_audit
961
924
  # Everything is good
962
925
  => #<Truemail::Auditor:0x00005580df358828
963
926
  @result=
964
927
  #<struct Truemail::Auditor::Result
928
+ current_host_ip="127.0.0.1",
965
929
  warnings={}>,
966
930
  configuration=
967
931
  #<Truemail::Configuration:0x00005615e86327a8
@@ -980,12 +944,15 @@ Truemail.host_audit
980
944
  @whitelist_validation=false,
981
945
  @whitelisted_domains=[]>
982
946
 
983
- # Has PTR warning
947
+ # Has audit warnings
984
948
  => #<Truemail::Auditor:0x00005580df358828
985
949
  @result=
986
950
  #<struct Truemail::Auditor::Result
987
- warnings=
988
- {:ptr=>"ptr record does not reference to current verifier domain"}>,
951
+ current_host_ip="127.0.0.1",
952
+ warnings={
953
+ :dns=>"A-record of verifier domain not refers to current host ip address",
954
+ :ptr=>"PTR-record does not reference to current verifier domain"
955
+ },
989
956
  configuration=
990
957
  #<Truemail::Configuration:0x00005615e86327a8
991
958
  @blacklisted_domains=[],
@@ -1004,6 +971,91 @@ Truemail.host_audit
1004
971
  @whitelisted_domains=[]>
1005
972
  ```
1006
973
 
974
+ ### Event logger
975
+
976
+ Truemail gem allows to output tracking events to stdout/file or both of these. Please note, at least one of the outputs must exist. Tracking event by default is `:error`
977
+
978
+ ```ruby
979
+ Truemail.configure do |config|
980
+ config.logger = { tracking_event: :all, stdout: true, log_absolute_path: '/home/app/log/truemail.log' }
981
+ end
982
+ ```
983
+
984
+ #### Available tracking events
985
+
986
+ - `:all`, all detected events including success validation cases
987
+ - `:unrecognized_error`, unrecognized errors only (when `smtp_safe_check = true` and SMTP server does not return an exact answer that the email does not exist)
988
+ - `:recognized_error`, recognized errors only
989
+ - `:error`, recognized and unrecognized errors only
990
+
991
+ ### JSON serializers
992
+
993
+ Truemail has built in JSON serializers for `Truemail::Auditor` and `Truemail::Validator` instances, so you can represent your host audition or email validation result as json. Also you can use [#as_json](#as_json) helper for shortcuting.
994
+
995
+ #### Auditor JSON serializer
996
+
997
+ ```ruby
998
+ Truemail::Log::Serializer::AuditorJson.call(Truemail.host_audit)
999
+
1000
+ =>
1001
+ # Serialized Truemail::Auditor instance
1002
+ {
1003
+ "date": "2020-08-31 22:33:43 +0300",
1004
+ "current_host_ip": "127.0.0.1",
1005
+ "warnings": {
1006
+ "dns": "A-record of verifier domain not refers to current host ip address", "ptr": "PTR-record does not reference to current verifier domain"
1007
+ },
1008
+ "configuration": {
1009
+ "validation_type_by_domain": null,
1010
+ "whitelist_validation": false,
1011
+ "whitelisted_domains": null,
1012
+ "blacklisted_domains": null,
1013
+ "not_rfc_mx_lookup_flow": false,
1014
+ "smtp_safe_check": false,
1015
+ "email_pattern": "default gem value",
1016
+ "smtp_error_body_pattern": "default gem value"
1017
+ }
1018
+ }
1019
+ ```
1020
+
1021
+ #### Validator JSON serializer
1022
+
1023
+ ```ruby
1024
+ Truemail::Log::Serializer::ValidatorJson.call(Truemail.validate('nonexistent_email@bestweb.com.ua'))
1025
+
1026
+ =>
1027
+ # Serialized Truemail::Validator instance
1028
+ {
1029
+ "date": "2019-10-28 10:15:51 +0200",
1030
+ "email": "nonexistent_email@bestweb.com.ua",
1031
+ "validation_type": "smtp",
1032
+ "success": false,
1033
+ "errors": {
1034
+ "smtp": "smtp error"
1035
+ },
1036
+ "smtp_debug": [
1037
+ {
1038
+ "mail_host": "213.180.193.89",
1039
+ "port_opened": true,
1040
+ "connection": true,
1041
+ "errors": {
1042
+ "rcptto": "550 5.7.1 No such user!\n"
1043
+ }
1044
+ }
1045
+ ],
1046
+ "configuration": {
1047
+ "validation_type_by_domain": null,
1048
+ "whitelist_validation": false,
1049
+ "whitelisted_domains": null,
1050
+ "blacklisted_domains": null,
1051
+ "not_rfc_mx_lookup_flow": false,
1052
+ "smtp_safe_check": false,
1053
+ "email_pattern": "default gem value",
1054
+ "smtp_error_body_pattern": "default gem value"
1055
+ }
1056
+ }
1057
+ ```
1058
+
1007
1059
  ### Truemail helpers
1008
1060
 
1009
1061
  #### .valid?
@@ -1018,15 +1070,38 @@ Truemail.valid?('email@example.com')
1018
1070
 
1019
1071
  #### #as_json
1020
1072
 
1021
- You can use `#as_json` helper for represent `Truemail::Validator` instance as json. Under the hood it uses internal json serializer [`Truemail::Log::Serializer::Json`](#json-serializer):
1073
+ You can use `#as_json` helper for represent `Truemail::Auditor` or `Truemail::Validator` instances as json. Under the hood it uses internal json `Truemail::Log::Serializer::AuditorJson` and `Truemail::Log::Serializer::ValidatorJson` [serializers](#json-serializers):
1022
1074
 
1023
1075
  ```ruby
1076
+ Truemail.host_audit.as_json
1077
+
1078
+ =>
1079
+ # Serialized Truemail::Auditor instance
1080
+ {
1081
+ "date": "2020-08-31 22:33:43 +0300",
1082
+ "current_host_ip": "127.0.0.1",
1083
+ "warnings": {
1084
+ "dns": "A-record of verifier domain not refers to current host ip address", "ptr": "PTR-record does not reference to current verifier domain"
1085
+ },
1086
+ "configuration": {
1087
+ "validation_type_by_domain": null,
1088
+ "whitelist_validation": false,
1089
+ "whitelisted_domains": null,
1090
+ "blacklisted_domains": null,
1091
+ "not_rfc_mx_lookup_flow": false,
1092
+ "smtp_safe_check": false,
1093
+ "email_pattern": "default gem value",
1094
+ "smtp_error_body_pattern": "default gem value"
1095
+ }
1096
+ }
1097
+
1098
+
1024
1099
  Truemail.validate('nonexistent_email@bestweb.com.ua').as_json
1025
1100
 
1026
1101
  =>
1027
1102
  # Serialized Truemail::Validator instance
1028
1103
  {
1029
- "date": "2020-02-01 10:00:00 +0200",
1104
+ "date": "2020-05-10 10:00:00 +0200",
1030
1105
  "email": "nonexistent_email@bestweb.com.ua",
1031
1106
  "validation_type": "smtp",
1032
1107
  "success": false,
@@ -1048,6 +1123,7 @@ Truemail.validate('nonexistent_email@bestweb.com.ua').as_json
1048
1123
  "whitelist_validation": false,
1049
1124
  "whitelisted_domains": null,
1050
1125
  "blacklisted_domains": null,
1126
+ "not_rfc_mx_lookup_flow": false,
1051
1127
  "smtp_safe_check": false,
1052
1128
  "email_pattern": "default gem value",
1053
1129
  "smtp_error_body_pattern": "default gem value"
@@ -1090,15 +1166,15 @@ end
1090
1166
 
1091
1167
  ## Truemail family
1092
1168
 
1093
- All Truemail extensions: https://github.com/truemail-rb
1169
+ All Truemail solutions: https://truemail-rb.org
1094
1170
 
1095
1171
  | Name | Type | Description |
1096
1172
  | --- | --- | --- |
1097
- | [truemail server](https://github.com/truemail-rb/truemail-rack) | ruby app | Lightweight rack based web API wrapper for Truemail |
1173
+ | [truemail server](https://github.com/truemail-rb/truemail-rack) | ruby app | Lightweight rack based web API wrapper for Truemail gem |
1098
1174
  | [truemail-rack-docker](https://github.com/truemail-rb/truemail-rack-docker-image) | docker image | Lightweight rack based web API [dockerized image](https://hub.docker.com/r/truemail/truemail-rack) :whale: of Truemail server |
1099
- | [truemail-ruby-client](https://github.com/truemail-rb/truemail-ruby-client) | ruby gem | Truemail web API client library for Ruby |
1100
- | [truemail-crystal-client](https://github.com/truemail-rb/truemail-crystal-client) | crystal shard | Truemail web API client library for Crystal |
1101
- | [truemail-rspec](https://github.com/truemail-rb/truemail-rspec) | ruby gem | Truemail configuration and validator RSpec helpers |
1175
+ | [truemail-ruby-client](https://github.com/truemail-rb/truemail-ruby-client) | ruby gem | Web API Ruby client for Truemail Server |
1176
+ | [truemail-crystal-client](https://github.com/truemail-rb/truemail-crystal-client) | crystal shard | Web API Crystal client for Truemail Server |
1177
+ | [truemail-rspec](https://github.com/truemail-rb/truemail-rspec) | ruby gem | Truemail configuration, auditor and validator RSpec helpers |
1102
1178
 
1103
1179
  ## Contributing
1104
1180
 
@@ -1120,8 +1196,3 @@ Everyone interacting in the Truemail project’s codebases, issue trackers, chat
1120
1196
  ## Versioning
1121
1197
 
1122
1198
  Truemail uses [Semantic Versioning 2.0.0](https://semver.org)
1123
-
1124
- ---
1125
- <a href="https://rubygarage.org/"><img src="https://rubygarage.s3.amazonaws.com/assets/assets/rg_color_logo_horizontal-919afc51a81d2e40cb6a0b43ee832e3fcd49669d06785156d2d16fd0d799f89e.png" alt="RubyGarage Logo" width="415" height="128"></a>
1126
-
1127
- RubyGarage is a leading software development and consulting company in Eastern Europe. Our main expertise includes Ruby and Ruby on Rails, but we successfully employ other technologies to deliver the best results to our clients. [Check out our portfolio](https://rubygarage.org/portfolio) for even more exciting works!
@@ -1,10 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'truemail/core'
3
+ require_relative 'truemail/core'
4
4
 
5
5
  module Truemail
6
6
  INCOMPLETE_CONFIG = 'verifier_email is required parameter'
7
7
  NOT_CONFIGURED = 'use Truemail.configure before or pass custom configuration'
8
+ INVALID_TYPE = 'email should be a String'
8
9
 
9
10
  class << self
10
11
  def configuration(&block)
@@ -25,10 +26,12 @@ module Truemail
25
26
  end
26
27
 
27
28
  def validate(email, custom_configuration: nil, **options)
29
+ check_argument_type(email)
28
30
  Truemail::Validator.new(email, configuration: determine_configuration(custom_configuration), **options).run
29
31
  end
30
32
 
31
33
  def valid?(email, **options)
34
+ check_argument_type(email)
32
35
  validate(email, **options).result.valid?
33
36
  end
34
37
 
@@ -38,8 +41,12 @@ module Truemail
38
41
 
39
42
  private
40
43
 
41
- def raise_unless(condition, message)
42
- raise Truemail::ConfigurationError, message unless condition
44
+ def raise_unless(condition, message, error_class = Truemail::ConfigurationError)
45
+ raise error_class, message unless condition
46
+ end
47
+
48
+ def check_argument_type(argument)
49
+ raise_unless(argument.is_a?(String), Truemail::INVALID_TYPE, Truemail::TypeError)
43
50
  end
44
51
 
45
52
  def determine_configuration(custom_configuration)
@@ -3,12 +3,20 @@
3
3
  module Truemail
4
4
  module Audit
5
5
  class Base < Truemail::Worker
6
+ require 'net/http'
7
+ require 'ipaddr'
8
+ require 'resolv'
9
+
6
10
  private
7
11
 
8
12
  def add_warning(message)
9
13
  result.warnings[self.class.name.split('::').last.downcase.to_sym] = message
10
14
  end
11
15
 
16
+ def current_host_ip
17
+ result.current_host_ip
18
+ end
19
+
12
20
  def configuration
13
21
  result.configuration
14
22
  end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Truemail
4
+ module Audit
5
+ class Dns < Truemail::Audit::Base
6
+ VERIFIER_DOMAIN_NOT_REFER = 'A-record of verifier domain not refers to current host ip address'
7
+
8
+ def run
9
+ return if verifier_domain_refer_to_current_host_ip?
10
+ add_warning(Truemail::Audit::Dns::VERIFIER_DOMAIN_NOT_REFER)
11
+ end
12
+
13
+ private
14
+
15
+ def a_record
16
+ Truemail::Wrapper.call(configuration: configuration) do
17
+ Resolv::DNS.new.getaddress(verifier_domain).to_s
18
+ end
19
+ end
20
+
21
+ def verifier_domain_refer_to_current_host_ip?
22
+ a_record.eql?(current_host_ip)
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Truemail
4
+ module Audit
5
+ class Ip < Truemail::Audit::Base
6
+ GET_MY_IP_URL = 'https://api.ipify.org'
7
+ IPIFY_ERROR = 'impossible to detect current host address via third party service'
8
+
9
+ def run
10
+ return add_warning(Truemail::Audit::Ip::IPIFY_ERROR) unless detect_current_host_ip
11
+ Truemail::Audit::Dns.check(result)
12
+ Truemail::Audit::Ptr.check(result)
13
+ end
14
+
15
+ private
16
+
17
+ def detect_ip_via_ipify
18
+ Net::HTTP.get(URI(Truemail::Audit::Ip::GET_MY_IP_URL))
19
+ end
20
+
21
+ def detect_current_host_ip
22
+ result.current_host_ip = Truemail::Wrapper.call(configuration: configuration) do
23
+ detect_ip_via_ipify
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end