diff --git a/CHANGELOG.md b/CHANGELOG.md index 83f54ee..e60df88 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,12 +22,16 @@ Please file a bug if you notice a violation of semantic versioning. ### Changed +- auth-sanitizer v0.1.3 + ### Deprecated ### Removed ### Fixed +- Load `auth-sanitizer` through an internal isolated loader so requiring `oauth/tty` does not add top-level `Auth` or `AuthSanitizer` constants that may collide with downstream applications. + ### Security ## [1.0.7] - 2026-05-16 diff --git a/Gemfile.lock b/Gemfile.lock index a19a0dc..b3a56de 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,8 +1,8 @@ PATH remote: . specs: - oauth-tty (1.0.7) - auth-sanitizer (~> 0.1) + oauth-tty (1.0.8) + auth-sanitizer (~> 0.1, >= 0.1.3) cgi version_gem (~> 1.1, >= 1.1.9) @@ -17,7 +17,7 @@ GEM rake (>= 10) thor (>= 0.14) ast (2.4.3) - auth-sanitizer (0.1.2) + auth-sanitizer (0.1.3) version_gem (~> 1.1, >= 1.1.9) backports (3.25.3) base64 (0.3.0) @@ -99,7 +99,7 @@ GEM rdoc (>= 4.0.0) reline (>= 0.4.2) json (2.19.5) - kettle-dev (1.2.4) + kettle-dev (2.0.0) kettle-soup-cover (1.1.1) simplecov (~> 0.22) simplecov-cobertura (~> 3.0) @@ -151,10 +151,12 @@ GEM racc (~> 1.4) nokogiri (1.19.3-x86_64-linux-musl) racc (~> 1.4) - oauth (1.1.3) + oauth (1.1.4) + auth-sanitizer (~> 0.1, >= 0.1.2) base64 (~> 0.1) - oauth-tty (~> 1.0, >= 1.0.6) - snaky_hash (~> 2.0) + cgi + oauth-tty (~> 1.0, >= 1.0.7) + snaky_hash (~> 2.0, >= 2.0.4) version_gem (~> 1.1, >= 1.1.9) ostruct (0.6.3) parallel (1.28.0) @@ -302,7 +304,7 @@ GEM simplecov-rcov (0.3.7) simplecov (>= 0.4.1) simplecov_json_formatter (0.1.4) - snaky_hash (2.0.3) + snaky_hash (2.0.4) hashie (>= 0.1.0, < 6) version_gem (>= 1.1.8, < 3) standard (1.54.0) @@ -354,7 +356,7 @@ GEM yard yard-relative_markdown_links (0.5.0) nokogiri (>= 1.14.3, < 2) - zeitwerk (2.7.5) + zeitwerk (2.8.1) zlib (3.2.3) PLATFORMS @@ -368,18 +370,18 @@ PLATFORMS x86_64-linux-musl DEPENDENCIES - appraisal2 (~> 3.0) + appraisal2 (~> 3.0, >= 3.0.6) backports (~> 3.25, >= 3.25.1) benchmark (~> 0.4, >= 0.4.1) - bundler-audit (~> 0.9.2) + bundler-audit (~> 0.9.3) debug (>= 1.1) erb (~> 5.0) gem_bench (~> 2.0, >= 2.0.5) gitmoji-regex (~> 1.0, >= 1.0.3) irb (~> 1.15, >= 1.15.2) - kettle-dev (~> 1.1) + kettle-dev (~> 2.0) kettle-soup-cover (~> 1.0, >= 1.0.10) - kettle-test (~> 1.0) + kettle-test (~> 1.0, >= 1.0.10) kramdown (~> 2.5, >= 2.5.1) kramdown-parser-gfm (~> 1.1) mocha (~> 3.0) @@ -393,7 +395,7 @@ DEPENDENCIES reek (~> 6.5) require_bench (~> 1.0, >= 1.0.4) rest-client (~> 2.1) - rspec-pending_for (~> 0.0, >= 0.0.17) + rspec-pending_for (~> 0.1, >= 0.1.20) rubocop-lts (~> 10.0) rubocop-on-rbs (~> 1.8) rubocop-packaging (~> 0.6, >= 0.6.0) @@ -401,7 +403,7 @@ DEPENDENCIES rubocop-ruby2_3 ruby-progressbar (~> 1.13) standard (>= 1.50) - stone_checksums (~> 1.0, >= 1.0.2) + stone_checksums (~> 1.0, >= 1.0.3) stringio (>= 3.0) typhoeus (>= 0.1.13) vcr (>= 4) @@ -415,7 +417,7 @@ CHECKSUMS ansi (1.6.0) sha256=ac9ea0c0ea8d32fb4e271348e609963ac78882f34b73836c2a02b3622e666658 appraisal2 (3.0.6) sha256=09387896b6c8c8c0ff0749af691ddff5e3168de2f06b591a80d8fd8b6394d147 ast (2.4.3) sha256=954615157c1d6a382bc27d690d973195e79db7f55e9765ac7c481c60bdb4d383 - auth-sanitizer (0.1.2) sha256=29f7638d74b2a19ff890008f1561165668a78969a4d90bc85e991128825a7c03 + auth-sanitizer (0.1.3) sha256=51002d96e921eb9610b197f39de92ae63df11eeb3c5f2bfd7829feb725911487 backports (3.25.3) sha256=94298d32dc3c40ca15633b54e282780b49e2db0c045f602ea1907e4f63a17235 base64 (0.3.0) sha256=27337aeabad6ffae05c265c450490628ef3ebd4b67be58257393227588f5a97b benchmark (0.5.0) sha256=465df122341aedcb81a2a24b4d3bd19b6c67c1530713fd533f3ff034e419236c @@ -457,7 +459,7 @@ CHECKSUMS io-console (0.8.2) sha256=d6e3ae7a7cc7574f4b8893b4fca2162e57a825b223a177b7afa236c5ef9814cc irb (1.18.0) sha256=de9454a0703a54704b9811a5ef31a60c86949fbf4013fcf244fabc7c775248e3 json (2.19.5) sha256=218a18553e4801d579ca7e0f5bc72bafd776d7397238a1fb4e74db5b0a812c59 - kettle-dev (1.2.4) sha256=71373c67fe7eb0a9656e70dfd10cf226a15083b6d1be18dafcb5360f21ee98b6 + kettle-dev (2.0.0) sha256=f3cd1a2f8cc4f1fcc573d7e9177644873cfdfe455e26365416b4290ea09490b5 kettle-soup-cover (1.1.1) sha256=2303885a9d8485d8d43cb250bcf73570f6b6fb997526beeaef3ef54e3501d445 kettle-test (1.0.10) sha256=ddefc5d54b290ee6dbe5a3983128f6948fa63f624ca676c1e6cfffc9b6878179 kramdown (2.5.2) sha256=1ba542204c66b6f9111ff00dcc26075b95b220b07f2905d8261740c82f7f02fa @@ -478,8 +480,8 @@ CHECKSUMS nokogiri (1.19.3-x86_64-darwin) sha256=77f3fba57d46c53ab31e62fc6c28f705109d1bf6264356c76f132b2be5728d4d nokogiri (1.19.3-x86_64-linux-gnu) sha256=2f5078620fe12e83669b5b17311b32532a8153d02eee7ad06948b926d6080976 nokogiri (1.19.3-x86_64-linux-musl) sha256=248c906d2166eca5efb56d52fdee5f9a1f51d69a72e2b64fdac647b4ce39ea3f - oauth (1.1.3) sha256=71ca1b534561bf31a9b2aee01147384064b555e796d1a0fe2591806bb4bdd633 - oauth-tty (1.0.7) + oauth (1.1.4) sha256=dc836253efa583054fa443ab41bafe70fd24498b4157eb524e5c3a45b5f10d0b + oauth-tty (1.0.8) ostruct (0.6.3) sha256=95a2ed4a4bd1d190784e666b47b2d3f078e4a9efda2fccf18f84ddc6538ed912 parallel (1.28.0) sha256=33e6de1484baf2524792d178b0913fc8eb94c628d6cfe45599ad4458c638c970 parser (3.3.11.1) sha256=d17ace7aabe3e72c3cc94043714be27cc6f852f104d81aa284c2281aecc65d54 @@ -535,7 +537,7 @@ CHECKSUMS simplecov-lcov (0.9.0) sha256=7a77a31e200a595ed4b0249493056efd0c920601f53d2ef135ca34ee796346cd simplecov-rcov (0.3.7) sha256=372f50bf6df6b6350b7d0c840f2f8bdabe021861a43c26877b747c9ac96139fc simplecov_json_formatter (0.1.4) sha256=529418fbe8de1713ac2b2d612aa3daa56d316975d307244399fa4838c601b428 - snaky_hash (2.0.3) sha256=25a3d299566e8153fb02fa23fd9a9358845950f7a523ddbbe1fa1e0d79a6d456 + snaky_hash (2.0.4) sha256=2b12758c57defa6796341a1620f84b1a23737421d8d7e2575d0550b53cc4fece standard (1.54.0) sha256=7a4b08f83d9893083c8f03bc486f0feeb6a84d48233b40829c03ef4767ea0100 standard-custom (1.0.2) sha256=424adc84179a074f1a2a309bb9cf7cd6bfdb2b6541f20c6bf9436c0ba22a652b standard-performance (1.9.0) sha256=49483d31be448292951d80e5e67cdcb576c2502103c7b40aec6f1b6e9c88e3f2 @@ -556,7 +558,7 @@ CHECKSUMS yard (0.9.43) sha256=cf8733a8f0485df2a162927e9b5f182215a61f6d22de096b8f402c726a1c5821 yard-junk (0.1.0) sha256=e85fe2ec1afa47313decd333447b53458cb1ed49b510b70015fdc3041a94bcdd yard-relative_markdown_links (0.5.0) sha256=d5158786196bfb82ed8f6880cefea2ef3072cc9e774ecebd7803e0db9bbb3a71 - zeitwerk (2.7.5) sha256=d8da92128c09ea6ec62c949011b00ed4a20242b255293dd66bf41545398f73dd + zeitwerk (2.8.1) sha256=1c85e0f28954d68cd16e575da37f26846f609b68d80b5942ccfd31030c2449d5 zlib (3.2.3) sha256=5bd316698b32f31a64ab910a8b6c282442ca1626a81bbd6a1674e8522e319c20 BUNDLED WITH diff --git a/lib/oauth/tty.rb b/lib/oauth/tty.rb index c6f1f17..2b210f2 100644 --- a/lib/oauth/tty.rb +++ b/lib/oauth/tty.rb @@ -5,7 +5,6 @@ require "optparse" # external gems -require "auth/sanitizer" require "version_gem" # For initial release as a standalone gem, this gem must not declare oauth as a dependency, @@ -15,6 +14,7 @@ # this gem's version require_relative "tty/version" +require_relative "tty/auth_sanitizer" # Configure version before loading the rest of the library OAuth::TTY::Version.class_eval do diff --git a/lib/oauth/tty/auth_sanitizer.rb b/lib/oauth/tty/auth_sanitizer.rb new file mode 100644 index 0000000..af7def2 --- /dev/null +++ b/lib/oauth/tty/auth_sanitizer.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +module OAuth + module TTY + AUTH_SANITIZER = begin + auth_sanitizer_requirement = Gem::Requirement.new("~> 0.1", ">= 0.1.3") + auth_sanitizer_spec = Gem.loaded_specs["auth-sanitizer"] + unless auth_sanitizer_spec && auth_sanitizer_requirement.satisfied_by?(auth_sanitizer_spec.version) + auth_sanitizer_spec = Gem::Specification.find_by_name("auth-sanitizer", auth_sanitizer_requirement) + end + + auth_sanitizer_loader_path = File.join( + auth_sanitizer_spec.full_gem_path, + "lib/auth_sanitizer/loader.rb", + ) + unless File.file?(auth_sanitizer_loader_path) + raise LoadError, "oauth-tty requires auth-sanitizer #{auth_sanitizer_requirement}; " \ + "loader not found at #{auth_sanitizer_loader_path}" + end + + auth_sanitizer_loader_namespace = Module.new + auth_sanitizer_loader_namespace.module_eval( + File.read(auth_sanitizer_loader_path), + auth_sanitizer_loader_path, + 1, + ) + + auth_sanitizer_loader_namespace + .const_get(:AuthSanitizer) + .const_get(:Loader) + .load_isolated + end + end +end diff --git a/lib/oauth/tty/command.rb b/lib/oauth/tty/command.rb index bf0da9e..ea5cde4 100644 --- a/lib/oauth/tty/command.rb +++ b/lib/oauth/tty/command.rb @@ -4,11 +4,11 @@ module OAuth module TTY # Base class for oauth-tty commands. # - # Includes {Auth::Sanitizer::FilteredAttributes} so inspect output redacts + # Includes {OAuth::TTY::AUTH_SANITIZER::FilteredAttributes} so inspect output redacts # the accumulated command options hash, which may contain consumer or token # secrets read from CLI flags or option files. class Command - include Auth::Sanitizer::FilteredAttributes + include OAuth::TTY::AUTH_SANITIZER::FilteredAttributes # Redact parser-related state from inspect output because it can include # credential-bearing CLI arguments and parser internals that retain them. diff --git a/lib/oauth/tty/version.rb b/lib/oauth/tty/version.rb index 5411c52..747a652 100644 --- a/lib/oauth/tty/version.rb +++ b/lib/oauth/tty/version.rb @@ -3,7 +3,7 @@ module OAuth module TTY module Version - VERSION = "1.0.7" + VERSION = "1.0.8" end VERSION = Version::VERSION # Traditional Constant Location end diff --git a/oauth-tty.gemspec b/oauth-tty.gemspec index 7949300..f5d775f 100644 --- a/oauth-tty.gemspec +++ b/oauth-tty.gemspec @@ -98,7 +98,7 @@ Gem::Specification.new do |spec| spec.add_dependency("cgi", ">= 0") # Utilities - spec.add_dependency("auth-sanitizer", "~> 0.1") + spec.add_dependency("auth-sanitizer", "~> 0.1", ">= 0.1.3") # ruby >= 2.2.0 spec.add_dependency("version_gem", "~> 1.1", ">= 1.1.9") # ruby >= 2.2.0 # NOTE: It is preferable to list development dependencies in the gemspec due to increased @@ -115,10 +115,10 @@ Gem::Specification.new do |spec| # and preferably a modular one (see gemfiles/modular/*.gemfile). # Dev, Test, & Release Tasks - spec.add_development_dependency("kettle-dev", "~> 1.1") # ruby >= 2.3.0 + spec.add_development_dependency("kettle-dev", "~> 2.0") # ruby >= 2.3.0 # Security - spec.add_development_dependency("bundler-audit", "~> 0.9.2") # ruby >= 2.0.0 + spec.add_development_dependency("bundler-audit", "~> 0.9.3") # ruby >= 2.0.0 # Tasks spec.add_development_dependency("rake", "~> 13.0") # ruby >= 2.2.0 @@ -127,18 +127,18 @@ Gem::Specification.new do |spec| spec.add_development_dependency("require_bench", "~> 1.0", ">= 1.0.4") # ruby >= 2.2.0 # Testing - spec.add_development_dependency("appraisal2", "~> 3.0") # ruby >= 1.8.7, for testing against multiple versions of dependencies - spec.add_development_dependency("kettle-test", "~> 1.0") # ruby >= 2.3 + spec.add_development_dependency("appraisal2", "~> 3.0", ">= 3.0.6") # ruby >= 1.8.7, for testing against multiple versions of dependencies + spec.add_development_dependency("kettle-test", "~> 1.0", ">= 1.0.10") # ruby >= 2.3 spec.add_development_dependency("mocha", "~> 3.0") spec.add_development_dependency("rack", "~> 2.0") spec.add_development_dependency("rack-test", "~> 2.0") spec.add_development_dependency("rest-client", "~> 2.1") - spec.add_development_dependency("rspec-pending_for", "~> 0.0", ">= 0.0.17") # ruby >= 2.3, used to skip specs on incompatible Rubies + spec.add_development_dependency("rspec-pending_for", "~> 0.1", ">= 0.1.20") # ruby >= 2.3, used to skip specs on incompatible Rubies spec.add_development_dependency("typhoeus", ">= 0.1.13") # Releasing spec.add_development_dependency("ruby-progressbar", "~> 1.13") # ruby >= 0 - spec.add_development_dependency("stone_checksums", "~> 1.0", ">= 1.0.2") # ruby >= 2.2.0 + spec.add_development_dependency("stone_checksums", "~> 1.0", ">= 1.0.3") # ruby >= 2.2.0 # Git integration (optional) # The 'git' gem is optional; oauth-tty falls back to shelling out to `git` if it is not present. diff --git a/sig/oauth/tty/command.rbs b/sig/oauth/tty/command.rbs index 0891ece..6541788 100644 --- a/sig/oauth/tty/command.rbs +++ b/sig/oauth/tty/command.rbs @@ -1,7 +1,7 @@ module OAuth module TTY class Command - include Auth::Sanitizer::FilteredAttributes + include OAuth::TTY::AUTH_SANITIZER::FilteredAttributes def initialize: (untyped stdout, untyped stdin, untyped stderr, untyped arguments) -> void def run: () -> untyped diff --git a/spec/oauth/tty/auth_sanitizer_spec.rb b/spec/oauth/tty/auth_sanitizer_spec.rb new file mode 100644 index 0000000..964c614 --- /dev/null +++ b/spec/oauth/tty/auth_sanitizer_spec.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +RSpec.describe "OAuth::TTY::AUTH_SANITIZER" do + it "provides filtered attributes for OAuth::TTY commands" do + expect(OAuth::TTY::Command.ancestors).to include(OAuth::TTY::AUTH_SANITIZER::FilteredAttributes) + end +end