nondisposable 0.1.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.simplecov +35 -0
- data/AGENTS.md +5 -0
- data/Appraisals +20 -0
- data/CHANGELOG.md +10 -1
- data/CLAUDE.md +5 -0
- data/README.md +37 -0
- data/Rakefile +10 -1
- data/gemfiles/rails_7.2.gemfile +18 -0
- data/gemfiles/rails_8.0.gemfile +18 -0
- data/gemfiles/rails_8.1.gemfile +18 -0
- data/lib/nondisposable/domain_list_updater.rb +7 -7
- data/lib/nondisposable/email_validator.rb +1 -1
- data/lib/nondisposable/engine.rb +0 -4
- data/lib/nondisposable/version.rb +1 -1
- data/lib/nondisposable.rb +4 -2
- metadata +10 -7
- data/lib/nondisposable/railtie.rb +0 -9
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6d6da844eae687a1d72201694a880a5ec5f16dcbd5e498de792a19d421027e6b
|
|
4
|
+
data.tar.gz: ea77c8f6ea5ddf4726f95b3438fadb7c7f0dedaed83bf7b674fdba78f95cbbed
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: af761f9347d7e630239973256600cb52996f166f8479908c2ee8d379cae8b46d2035455c4bc2dc3c305941d7fe393dcac634e8d6b287e95eeee4b8bf9271db64
|
|
7
|
+
data.tar.gz: f58d7598f288515f684aaffc55a9399e01398fc9644b5744fd8e136510e4e51d358db12b4b33f99a58c7d06b5a05bd06a5313ff8e5f9f35e2d8ce95166791d38
|
data/.simplecov
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# SimpleCov configuration file (auto-loaded before test suite)
|
|
4
|
+
# This keeps test_helper.rb clean and follows best practices
|
|
5
|
+
|
|
6
|
+
SimpleCov.start do
|
|
7
|
+
# Use SimpleFormatter for terminal-only output (no HTML generation)
|
|
8
|
+
formatter SimpleCov::Formatter::SimpleFormatter
|
|
9
|
+
|
|
10
|
+
# Track coverage for the lib directory (gem source code)
|
|
11
|
+
add_filter "/test/"
|
|
12
|
+
|
|
13
|
+
# Track the lib and app directories
|
|
14
|
+
track_files "{lib,app}/**/*.rb"
|
|
15
|
+
|
|
16
|
+
# Enable branch coverage for more detailed metrics
|
|
17
|
+
enable_coverage :branch
|
|
18
|
+
|
|
19
|
+
# Set minimum coverage threshold to prevent coverage regression
|
|
20
|
+
minimum_coverage line: 90, branch: 90
|
|
21
|
+
|
|
22
|
+
# Disambiguate parallel test runs
|
|
23
|
+
command_name "Job #{ENV['TEST_ENV_NUMBER']}" if ENV['TEST_ENV_NUMBER']
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Print coverage summary to terminal after tests complete
|
|
27
|
+
SimpleCov.at_exit do
|
|
28
|
+
SimpleCov.result.format!
|
|
29
|
+
puts "\n" + "=" * 60
|
|
30
|
+
puts "COVERAGE SUMMARY"
|
|
31
|
+
puts "=" * 60
|
|
32
|
+
puts "Line Coverage: #{SimpleCov.result.covered_percent.round(2)}%"
|
|
33
|
+
puts "Branch Coverage: #{SimpleCov.result.coverage_statistics[:branch]&.percent&.round(2) || 'N/A'}%"
|
|
34
|
+
puts "=" * 60
|
|
35
|
+
end
|
data/AGENTS.md
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
# AGENTS.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to AI Agents (like OpenAI's Codex, Cursor Agent, Claude Code, etc) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
Please go ahead and read the full context for this project at `.cursor/rules/0-overview.mdc` and `.cursor/rules/1-quality.mdc` now. Also read the README for a good overview of the project.
|
data/Appraisals
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Note: Rails < 7.2 is not compatible with Ruby 3.4
|
|
4
|
+
# (Logger became a bundled gem in Ruby 3.4, and only Rails 7.2+ handles this)
|
|
5
|
+
# See: https://stdgems.org/logger/
|
|
6
|
+
|
|
7
|
+
# Test against Rails 7.2 (minimum version compatible with Ruby 3.4)
|
|
8
|
+
appraise "rails-7.2" do
|
|
9
|
+
gem "rails", "~> 7.2.0"
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# Test against Rails 8.0
|
|
13
|
+
appraise "rails-8.0" do
|
|
14
|
+
gem "rails", "~> 8.0.0"
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Test against Rails 8.1 (latest)
|
|
18
|
+
appraise "rails-8.1" do
|
|
19
|
+
gem "rails", "~> 8.1.2"
|
|
20
|
+
end
|
data/CHANGELOG.md
CHANGED
|
@@ -1,4 +1,13 @@
|
|
|
1
|
-
## [
|
|
1
|
+
## [0.2.1] - 2026-01-17
|
|
2
|
+
|
|
3
|
+
- Add `[nondisposable]` prefix to all logger calls for better log identification
|
|
4
|
+
|
|
5
|
+
## [0.2.0] - 2026-01-16
|
|
6
|
+
|
|
7
|
+
- Fixed `NoMethodError` when email is `"@"` or malformed (empty domain after split)
|
|
8
|
+
- Removed non-existent asset references from engine (`nondisposable/application.css` and `.js`)
|
|
9
|
+
- Removed buggy `railtie.rb` file that attempted to include a class instead of a module
|
|
10
|
+
- Added comprehensive Minitest 6 test suite with 256 tests and 90%+ line / branch coverage
|
|
2
11
|
|
|
3
12
|
## [0.1.0] - 2024-09-25
|
|
4
13
|
|
data/CLAUDE.md
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
Please go ahead and read the full context for this project at `.cursor/rules/0-overview.mdc` and `.cursor/rules/1-quality.mdc` now. Also read the README for a good overview of the project.
|
data/README.md
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
# 🗑️ `nondisposable` - Block disposable email addresses from signing up to your Rails app
|
|
2
2
|
|
|
3
|
+
[](https://badge.fury.io/rb/nondisposable) [](https://github.com/rameerez/nondisposable/actions)
|
|
4
|
+
|
|
5
|
+
> [!TIP]
|
|
6
|
+
> **🚀 Ship your next Rails app 10x faster!** I've built **[RailsFast](https://railsfast.com/?ref=nondisposable)**, a production-ready Rails boilerplate template that comes with everything you need to launch a software business in days, not weeks. Go [check it out](https://railsfast.com/?ref=nondisposable)!
|
|
7
|
+
|
|
3
8
|
`nondisposable` is a Ruby gem that prevents users from signing up to your Rails app with disposable email addresses.
|
|
4
9
|
|
|
5
10
|
Simply add to your User model:
|
|
@@ -122,6 +127,38 @@ production:
|
|
|
122
127
|
schedule: every day at 3am US/Pacific
|
|
123
128
|
```
|
|
124
129
|
|
|
130
|
+
## Troubleshooting
|
|
131
|
+
|
|
132
|
+
### SSL certificate verify failed (unable to get certificate CRL)
|
|
133
|
+
|
|
134
|
+
If you see this error when running `Nondisposable::DomainListUpdater.update`:
|
|
135
|
+
|
|
136
|
+
```
|
|
137
|
+
SSL_connect returned=1 errno=0 peeraddr=[::1]:10011 state=error: certificate verify failed (unable to get certificate CRL) (OpenSSL::SSL::SSLError)
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
This is **not** a bug in `nondisposable`. It's a known incompatibility between OpenSSL 3.6.0 and older versions of Ruby's `openssl` gem (3.3.0 and earlier).
|
|
141
|
+
|
|
142
|
+
The fix is to update the `openssl` gem to version 3.3.1 or later **in your Rails project**.
|
|
143
|
+
|
|
144
|
+
Add this to your Rails' project `Gemfile`:
|
|
145
|
+
|
|
146
|
+
```ruby
|
|
147
|
+
gem "openssl", "~> 3.3.2"
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Then run:
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
bundle install
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
This issue is unlikely to occur in production, it's mostly a development-only issue. It's likely that the exact same codebase fails in development but works fine in production. It only occurs when you have OpenSSL 3.6.0 system-wide AND something intercepting HTTPS traffic (like Cursor's proxy). Users in production or using a regular terminal won't experience it.
|
|
157
|
+
|
|
158
|
+
This issue is more likely to occur if you're running your Rails console from within certain IDEs (like Cursor) that intercept HTTPS traffic through a local proxy. The updated `openssl` gem properly handles certificate verification in these environments.
|
|
159
|
+
|
|
160
|
+
For more details, see the [Ruby openssl gem issue](https://github.com/ruby/openssl/issues/949).
|
|
161
|
+
|
|
125
162
|
## Development
|
|
126
163
|
|
|
127
164
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
data/Rakefile
CHANGED
|
@@ -1,4 +1,13 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "bundler/gem_tasks"
|
|
4
|
-
|
|
4
|
+
require "rake/testtask"
|
|
5
|
+
|
|
6
|
+
Rake::TestTask.new(:test) do |t|
|
|
7
|
+
t.libs << "lib"
|
|
8
|
+
t.libs << "test"
|
|
9
|
+
t.test_files = FileList['test/**/*_test.rb']
|
|
10
|
+
t.warning = false
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
task default: %i[test]
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# This file was generated by Appraisal
|
|
2
|
+
|
|
3
|
+
source "https://rubygems.org"
|
|
4
|
+
|
|
5
|
+
gem "rake", "~> 13.0"
|
|
6
|
+
gem "rails", "~> 7.2.0"
|
|
7
|
+
|
|
8
|
+
group :test do
|
|
9
|
+
gem "appraisal"
|
|
10
|
+
gem "minitest", "~> 6.0"
|
|
11
|
+
gem "minitest-mock"
|
|
12
|
+
gem "minitest-reporters", "~> 1.6"
|
|
13
|
+
gem "webmock", "~> 3.19"
|
|
14
|
+
gem "sqlite3", "~> 2.1"
|
|
15
|
+
gem "simplecov", require: false
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
gemspec path: "../"
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# This file was generated by Appraisal
|
|
2
|
+
|
|
3
|
+
source "https://rubygems.org"
|
|
4
|
+
|
|
5
|
+
gem "rake", "~> 13.0"
|
|
6
|
+
gem "rails", "~> 8.0.0"
|
|
7
|
+
|
|
8
|
+
group :test do
|
|
9
|
+
gem "appraisal"
|
|
10
|
+
gem "minitest", "~> 6.0"
|
|
11
|
+
gem "minitest-mock"
|
|
12
|
+
gem "minitest-reporters", "~> 1.6"
|
|
13
|
+
gem "webmock", "~> 3.19"
|
|
14
|
+
gem "sqlite3", "~> 2.1"
|
|
15
|
+
gem "simplecov", require: false
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
gemspec path: "../"
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# This file was generated by Appraisal
|
|
2
|
+
|
|
3
|
+
source "https://rubygems.org"
|
|
4
|
+
|
|
5
|
+
gem "rake", "~> 13.0"
|
|
6
|
+
gem "rails", "~> 8.1.2"
|
|
7
|
+
|
|
8
|
+
group :test do
|
|
9
|
+
gem "appraisal"
|
|
10
|
+
gem "minitest", "~> 6.0"
|
|
11
|
+
gem "minitest-mock"
|
|
12
|
+
gem "minitest-reporters", "~> 1.6"
|
|
13
|
+
gem "webmock", "~> 3.19"
|
|
14
|
+
gem "sqlite3", "~> 2.1"
|
|
15
|
+
gem "simplecov", require: false
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
gemspec path: "../"
|
|
@@ -7,7 +7,7 @@ module Nondisposable
|
|
|
7
7
|
class DomainListUpdater
|
|
8
8
|
|
|
9
9
|
def self.update
|
|
10
|
-
Rails.logger.info "Refreshing list of disposable domains..."
|
|
10
|
+
Rails.logger.info "[nondisposable] Refreshing list of disposable domains..."
|
|
11
11
|
|
|
12
12
|
url = 'https://raw.githubusercontent.com/disposable-email-domains/disposable-email-domains/master/disposable_email_blocklist.conf'
|
|
13
13
|
|
|
@@ -19,29 +19,29 @@ module Nondisposable
|
|
|
19
19
|
downloaded_domains = response.body.split("\n")
|
|
20
20
|
raise "The list is empty. This might indicate a problem with the format." if downloaded_domains.empty?
|
|
21
21
|
|
|
22
|
-
Rails.logger.info "Downloaded list of disposable domains..."
|
|
22
|
+
Rails.logger.info "[nondisposable] Downloaded list of disposable domains..."
|
|
23
23
|
|
|
24
24
|
domains = (downloaded_domains + Nondisposable.configuration.additional_domains).uniq
|
|
25
25
|
domains -= Nondisposable.configuration.excluded_domains
|
|
26
26
|
|
|
27
27
|
ActiveRecord::Base.transaction do
|
|
28
|
-
Rails.logger.info "Updating disposable domains..."
|
|
28
|
+
Rails.logger.info "[nondisposable] Updating disposable domains..."
|
|
29
29
|
Nondisposable::DisposableDomain.delete_all
|
|
30
30
|
|
|
31
31
|
domains.each { |domain| Nondisposable::DisposableDomain.create(name: domain.downcase) }
|
|
32
32
|
end
|
|
33
33
|
|
|
34
|
-
Rails.logger.info "Finished updating disposable domains. Total domains: #{domains.count}"
|
|
34
|
+
Rails.logger.info "[nondisposable] Finished updating disposable domains. Total domains: #{domains.count}"
|
|
35
35
|
true
|
|
36
36
|
else
|
|
37
|
-
Rails.logger.error "Failed to download the list. HTTP Status: #{response.code}"
|
|
37
|
+
Rails.logger.error "[nondisposable] Failed to download the list. HTTP Status: #{response.code}"
|
|
38
38
|
false
|
|
39
39
|
end
|
|
40
40
|
rescue SocketError => e
|
|
41
|
-
Rails.logger.error "Network error occurred: #{e.message}"
|
|
41
|
+
Rails.logger.error "[nondisposable] Network error occurred: #{e.message}"
|
|
42
42
|
false
|
|
43
43
|
rescue StandardError => e
|
|
44
|
-
Rails.logger.error "An error occurred when trying to update the list of disposable domains: #{e.message}"
|
|
44
|
+
Rails.logger.error "[nondisposable] An error occurred when trying to update the list of disposable domains: #{e.message}"
|
|
45
45
|
false
|
|
46
46
|
end
|
|
47
47
|
end
|
|
@@ -14,7 +14,7 @@ module ActiveModel
|
|
|
14
14
|
record.errors.add(attribute, options[:message] || Nondisposable.configuration.error_message)
|
|
15
15
|
end
|
|
16
16
|
rescue StandardError => e
|
|
17
|
-
Rails.logger.error "Nondisposable validation error: #{e.message}"
|
|
17
|
+
Rails.logger.error "[nondisposable] Nondisposable validation error: #{e.message}"
|
|
18
18
|
record.errors.add(attribute, "is an invalid email address, cannot check if it's disposable")
|
|
19
19
|
end
|
|
20
20
|
end
|
data/lib/nondisposable/engine.rb
CHANGED
|
@@ -4,10 +4,6 @@ module Nondisposable
|
|
|
4
4
|
class Engine < ::Rails::Engine
|
|
5
5
|
isolate_namespace Nondisposable
|
|
6
6
|
|
|
7
|
-
initializer "nondisposable.assets.precompile" do |app|
|
|
8
|
-
app.config.assets.precompile += %w( nondisposable/application.css nondisposable/application.js )
|
|
9
|
-
end
|
|
10
|
-
|
|
11
7
|
config.generators do |g|
|
|
12
8
|
g.test_framework :rspec
|
|
13
9
|
g.fixture_replacement :factory_bot
|
data/lib/nondisposable.rb
CHANGED
|
@@ -4,6 +4,7 @@ require_relative "nondisposable/version"
|
|
|
4
4
|
require_relative "nondisposable/engine"
|
|
5
5
|
require_relative "nondisposable/email_validator"
|
|
6
6
|
require_relative "nondisposable/domain_list_updater"
|
|
7
|
+
|
|
7
8
|
module Nondisposable
|
|
8
9
|
class Error < StandardError; end
|
|
9
10
|
|
|
@@ -18,8 +19,9 @@ module Nondisposable
|
|
|
18
19
|
|
|
19
20
|
def self.disposable?(email)
|
|
20
21
|
return false if email.nil? || !email.include?('@')
|
|
21
|
-
domain = email.to_s.split('@').last
|
|
22
|
-
|
|
22
|
+
domain = email.to_s.split('@').last
|
|
23
|
+
return false if domain.nil? || domain.empty?
|
|
24
|
+
DisposableDomain.disposable?(domain.downcase)
|
|
23
25
|
end
|
|
24
26
|
|
|
25
27
|
class Configuration
|
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: nondisposable
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1
|
|
4
|
+
version: 0.2.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- rameerez
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: exe
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 2026-01-17 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: rails
|
|
@@ -33,11 +32,18 @@ executables: []
|
|
|
33
32
|
extensions: []
|
|
34
33
|
extra_rdoc_files: []
|
|
35
34
|
files:
|
|
35
|
+
- ".simplecov"
|
|
36
|
+
- AGENTS.md
|
|
37
|
+
- Appraisals
|
|
36
38
|
- CHANGELOG.md
|
|
39
|
+
- CLAUDE.md
|
|
37
40
|
- LICENSE.txt
|
|
38
41
|
- README.md
|
|
39
42
|
- Rakefile
|
|
40
43
|
- app/models/nondisposable/disposable_domain.rb
|
|
44
|
+
- gemfiles/rails_7.2.gemfile
|
|
45
|
+
- gemfiles/rails_8.0.gemfile
|
|
46
|
+
- gemfiles/rails_8.1.gemfile
|
|
41
47
|
- lib/generators/nondisposable/install_generator.rb
|
|
42
48
|
- lib/generators/nondisposable/templates/create_nondisposable_disposable_domains.rb.erb
|
|
43
49
|
- lib/generators/nondisposable/templates/disposable_email_domain_list_update_job.rb
|
|
@@ -46,7 +52,6 @@ files:
|
|
|
46
52
|
- lib/nondisposable/domain_list_updater.rb
|
|
47
53
|
- lib/nondisposable/email_validator.rb
|
|
48
54
|
- lib/nondisposable/engine.rb
|
|
49
|
-
- lib/nondisposable/railtie.rb
|
|
50
55
|
- lib/nondisposable/version.rb
|
|
51
56
|
- sig/nondisposable.rbs
|
|
52
57
|
homepage: https://github.com/rameerez/nondisposable
|
|
@@ -57,7 +62,6 @@ metadata:
|
|
|
57
62
|
homepage_uri: https://github.com/rameerez/nondisposable
|
|
58
63
|
source_code_uri: https://github.com/rameerez/nondisposable
|
|
59
64
|
changelog_uri: https://github.com/rameerez/nondisposable/blob/main/CHANGELOG.md
|
|
60
|
-
post_install_message:
|
|
61
65
|
rdoc_options: []
|
|
62
66
|
require_paths:
|
|
63
67
|
- lib
|
|
@@ -72,8 +76,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
72
76
|
- !ruby/object:Gem::Version
|
|
73
77
|
version: '0'
|
|
74
78
|
requirements: []
|
|
75
|
-
rubygems_version: 3.
|
|
76
|
-
signing_key:
|
|
79
|
+
rubygems_version: 3.6.2
|
|
77
80
|
specification_version: 4
|
|
78
81
|
summary: Block disposable emails from signing up to your Rails app
|
|
79
82
|
test_files: []
|