oauth2 2.0.18 → 2.0.19

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f43a3e156646bef90634677d617a155cff1f87d57ca030674f3ee05c160fa4d9
4
- data.tar.gz: 5a2d29e7cd920d4e2f515afc23896795477e5cb357e47b6f5c3d0c797194d54c
3
+ metadata.gz: 97a922901552727c225711855a88d45f56ad167b063ecb87477ac62db76e95e2
4
+ data.tar.gz: 6c31edbef7059f4644c46c273959c4c6e08f522d99306e94207bce8e82b10dc6
5
5
  SHA512:
6
- metadata.gz: 471a77bbc0bd8a428ce01ba42ba8e9cb0ad35793eb5f7ae352946b9dda9a448152280c3bdf445255adb47b7f45d65efa11bff2affc2c2200f8e43f57f2a19a91
7
- data.tar.gz: 6bae92dd35b1bf9efd38b4d3eceb2451c1016dbd9270947f74ba4ff389fa78420558df095acd8ff7404a2b8b2cdb9438983d1feb59751dd4252f2b7bc75c8d31
6
+ metadata.gz: 3a7ba7628e83cfc87d88bdcd1531256f85d5c053640444e76defda2c796b4d57c8c31aeee16784fc4d5c60c78ddeae5e99c44e91091c8fbd6927d6225101e60a
7
+ data.tar.gz: 206901137a350739ba8957bc65a2bf5ed3be2e85c7d2e03346320386b5901ed6178a359bbfb3a610d98c54bce4eda2cb8bffd657a87c2e567e80333cefc0d896
checksums.yaml.gz.sig CHANGED
Binary file
data/CHANGELOG.md CHANGED
@@ -30,6 +30,35 @@ Please file a bug if you notice a violation of semantic versioning.
30
30
 
31
31
  ### Security
32
32
 
33
+ ## [2.0.19] - 2026-05-15
34
+
35
+ - TAG: [v2.0.19][2.0.19t]
36
+ - COVERAGE: 100.00% -- 515/515 lines in 14 files
37
+ - BRANCH COVERAGE: 100.00% -- 174/174 branches in 14 files
38
+ - 89.11% documented
39
+
40
+ ### Added
41
+
42
+ - [gh!707][gh!707] Add `OAuth2.config[:filtered_label]` to configure the placeholder used for filtered sensitive values in inspected objects and debug logging output by @pboling
43
+ - [gh!707][gh!707] Add `OAuth2.config[:filtered_debug_keys]` to configure which key names have their values redacted from debug logging output by @pboling
44
+
45
+ ### Changed
46
+
47
+ - [gh!707][gh!707] Make inspect-time and debug-log filters snapshot their configuration at initialization time rather than tracking later config changes by @pboling
48
+ - [gh!714][gh!714]Refactor sensitive-value filtering to use `auth-sanitizer` while preserving `OAuth2::FilteredAttributes` as a permanent API alias by @pboling
49
+
50
+ ### Removed
51
+
52
+ - Remove the internal `OAuth2::ThingFilter` and `OAuth2::SanitizedLogger` implementations now provided by `auth-sanitizer` by @pboling
53
+
54
+ ### Security
55
+
56
+ - [gh!707][gh!707] Redact sensitive values from debug logging output, including Authorization headers and common token/secret fields in headers, query strings, form bodies, and JSON payloads by @pboling
57
+ - NOTE: debug logging has always been, and remains, opt-in. It is turned off by default.
58
+
59
+ [gh!707]: https://github.com/ruby-oauth/oauth2/pull/707
60
+ [gh!714]: https://github.com/ruby-oauth/oauth2/pull/714
61
+
33
62
  ## [2.0.18] - 2025-11-08
34
63
 
35
64
  - TAG: [v2.0.18][2.0.18t]
@@ -54,8 +83,6 @@ Please file a bug if you notice a violation of semantic versioning.
54
83
  - [gh!690][gh!690], [gh!691][gh!691], [gh!692][gh!692] - Add yard-fence
55
84
  - handle braces within code fences in markdown properly by @pboling
56
85
 
57
- ### Security
58
-
59
86
  [gh!683]: https://github.com/ruby-oauth/oauth2/pull/683
60
87
  [gh!684]: https://github.com/ruby-oauth/oauth2/pull/684
61
88
  [gh!685]: https://github.com/ruby-oauth/oauth2/pull/685
@@ -196,8 +223,6 @@ Please file a bug if you notice a violation of semantic versioning.
196
223
 
197
224
  - [gh!660][gh!660] - Links in README (including link to HEAD documentation) by @pboling
198
225
 
199
- ### Security
200
-
201
226
  [gh!660]: https://github.com/ruby-oauth/oauth2/pull/660
202
227
  [gh!657]: https://github.com/ruby-oauth/oauth2/pull/657
203
228
  [gh!656]: https://github.com/ruby-oauth/oauth2/pull/656
@@ -738,7 +763,9 @@ Please file a bug if you notice a violation of semantic versioning.
738
763
 
739
764
  [gemfiles/readme]: gemfiles/README.md
740
765
 
741
- [Unreleased]: https://github.com/ruby-oauth/oauth2/compare/v2.0.18...HEAD
766
+ [Unreleased]: https://github.com/ruby-oauth/oauth2/compare/v2.0.19...HEAD
767
+ [2.0.19]: https://github.com/ruby-oauth/oauth2/compare/v2.0.18...v2.0.19
768
+ [2.0.19t]: https://github.com/ruby-oauth/oauth2/releases/tag/v2.0.19
742
769
  [2.0.18]: https://github.com/ruby-oauth/oauth2/compare/v2.0.17...v2.0.18
743
770
  [2.0.18t]: https://github.com/ruby-oauth/oauth2/releases/tag/v2.0.18
744
771
  [2.0.17]: https://github.com/ruby-oauth/oauth2/compare/v2.0.16...v2.0.17
data/CITATION.cff CHANGED
File without changes
data/CODE_OF_CONDUCT.md CHANGED
File without changes
data/CONTRIBUTING.md CHANGED
File without changes
data/FUNDING.md CHANGED
File without changes
data/IRP.md CHANGED
File without changes
data/LICENSE.txt CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2017-2025 Peter H. Boling, of Galtzo.com, and oauth2 contributors
3
+ Copyright (c) 2017-2026 Peter H. Boling, of Galtzo.com, and oauth2 contributors
4
4
  Copyright (c) 2011-2013 Michael Bleigh and Intridea, Inc.
5
5
 
6
6
  Permission is hereby granted, free of charge, to any person obtaining a copy
data/OIDC.md CHANGED
File without changes
data/README.md CHANGED
@@ -1,32 +1,3 @@
1
- | 📍 NOTE |
2
- |-------------------------------------------------------------------------------------------------------------------------------------------------------------------|
3
- | RubyGems (the [GitHub org][rubygems-org], not the website) [suffered][draper-security] a [hostile takeover][ellen-takeover] in September 2025. |
4
- | Ultimately [4 maintainers][simi-removed] were [hard removed][martin-removed] and a reason has been given for only 1 of those, while 2 others resigned in protest. |
5
- | It is a [complicated story][draper-takeover] which is difficult to [parse quickly][draper-lies]. |
6
- | I'm adding notes like this to gems because I [don't condone theft][draper-theft] of repositories or gems from their rightful owners. |
7
- | If a similar theft happened with my repos/gems, I'd hope some would stand up for me. |
8
- | Disenfranchised former-maintainers have started [gem.coop][gem-coop]. |
9
- | Once available I will publish there exclusively; unless RubyCentral makes amends with the community. |
10
- | The ["Technology for Humans: Joel Draper"][reinteractive-podcast] podcast episode by [reinteractive][reinteractive] is the most cogent summary I'm aware of. |
11
- | See [here][gem-naming], [here][gem-coop] and [here][martin-ann] for more info on what comes next. |
12
- | What I'm doing: A (WIP) proposal for [bundler/gem scopes][gem-scopes], and a (WIP) proposal for a federated [gem server][gem-server]. |
13
-
14
- [rubygems-org]: https://github.com/rubygems/
15
- [draper-security]: https://joel.drapper.me/p/ruby-central-security-measures/
16
- [draper-takeover]: https://joel.drapper.me/p/ruby-central-takeover/
17
- [ellen-takeover]: https://pup-e.com/blog/goodbye-rubygems/
18
- [simi-removed]: https://www.reddit.com/r/ruby/s/gOk42POCaV
19
- [martin-removed]: https://bsky.app/profile/martinemde.com/post/3m3occezxxs2q
20
- [draper-lies]: https://joel.drapper.me/p/ruby-central-fact-check/
21
- [draper-theft]: https://joel.drapper.me/p/ruby-central/
22
- [reinteractive]: https://reinteractive.com/ruby-on-rails
23
- [gem-coop]: https://gem.coop
24
- [gem-naming]: https://github.com/gem-coop/gem.coop/issues/12
25
- [martin-ann]: https://martinemde.com/2025/10/05/announcing-gem-coop.html
26
- [gem-scopes]: https://github.com/galtzo-floss/bundle-namespace
27
- [gem-server]: https://github.com/galtzo-floss/gem-server
28
- [reinteractive-podcast]: https://youtu.be/_H4qbtC5qzU?si=BvuBU90R2wAqD2E6
29
-
30
1
  [![Galtzo FLOSS Logo by Aboling0, CC BY-SA 4.0][🖼️galtzo-i]][🖼️galtzo-discord] [![ruby-lang Logo, Yukihiro Matsumoto, Ruby Visual Identity Team, CC BY-SA 2.5][🖼️ruby-lang-i]][🖼️ruby-lang] [![oauth2 Logo by Chris Messina, CC BY-SA 3.0][🖼️oauth2-i]][🖼️oauth2]
31
2
 
32
3
  [🖼️galtzo-i]: https://logos.galtzo.com/assets/images/galtzo-floss/avatar-192px.svg
@@ -38,9 +9,7 @@
38
9
 
39
10
  # 🔐 OAuth 2.0 Authorization Framework
40
11
 
41
- ⭐️ including OAuth 2.1 draft spec & OpenID Connect (OIDC)
42
-
43
- [![Version][👽versioni]][👽version] [![GitHub tag (latest SemVer)][⛳️tag-img]][⛳️tag] [![License: MIT][📄license-img]][📄license-ref] [![Downloads Rank][👽dl-ranki]][👽dl-rank] [![Open Source Helpers][👽oss-helpi]][👽oss-help] [![CodeCov Test Coverage][🏀codecovi]][🏀codecov] [![Coveralls Test Coverage][🏀coveralls-img]][🏀coveralls] [![QLTY Test Coverage][🏀qlty-covi]][🏀qlty-cov] [![QLTY Maintainability][🏀qlty-mnti]][🏀qlty-mnt] [![CI Heads][🚎3-hd-wfi]][🚎3-hd-wf] [![CI Runtime Dependencies @ HEAD][🚎12-crh-wfi]][🚎12-crh-wf] [![CI Current][🚎11-c-wfi]][🚎11-c-wf] [![CI JRuby][🚎10-j-wfi]][🚎10-j-wf] [![Deps Locked][🚎13-🔒️-wfi]][🚎13-🔒️-wf] [![Deps Unlocked][🚎14-🔓️-wfi]][🚎14-🔓️-wf] [![CI Supported][🚎6-s-wfi]][🚎6-s-wf] [![CI Legacy][🚎4-lg-wfi]][🚎4-lg-wf] [![CI Unsupported][🚎7-us-wfi]][🚎7-us-wf] [![CI Ancient][🚎1-an-wfi]][🚎1-an-wf] [![CI Test Coverage][🚎2-cov-wfi]][🚎2-cov-wf] [![CI Style][🚎5-st-wfi]][🚎5-st-wf] [![CodeQL][🖐codeQL-img]][🖐codeQL] [![Apache SkyWalking Eyes License Compatibility Check][🚎15-🪪-wfi]][🚎15-🪪-wf]
12
+ [![Version][👽versioni]][👽version] [![GitHub tag (latest SemVer)][⛳️tag-img]][⛳️tag] [![License: MIT][📄license-img]][📄license-ref] [![Downloads Rank][👽dl-ranki]][👽dl-rank] [![CodeCov Test Coverage][🏀codecovi]][🏀codecov] [![Coveralls Test Coverage][🏀coveralls-img]][🏀coveralls] [![QLTY Test Coverage][🏀qlty-covi]][🏀qlty-cov] [![QLTY Maintainability][🏀qlty-mnti]][🏀qlty-mnt] [![CI Heads][🚎3-hd-wfi]][🚎3-hd-wf] [![CI Runtime Dependencies @ HEAD][🚎12-crh-wfi]][🚎12-crh-wf] [![CI Current][🚎11-c-wfi]][🚎11-c-wf] [![CI JRuby][🚎10-j-wfi]][🚎10-j-wf] [![Deps Locked][🚎13-🔒️-wfi]][🚎13-🔒️-wf] [![Deps Unlocked][🚎14-🔓️-wfi]][🚎14-🔓️-wf] [![CI Supported][🚎6-s-wfi]][🚎6-s-wf] [![CI Legacy][🚎4-lg-wfi]][🚎4-lg-wf] [![CI Unsupported][🚎7-us-wfi]][🚎7-us-wf] [![CI Ancient][🚎1-an-wfi]][🚎1-an-wf] [![CI Test Coverage][🚎2-cov-wfi]][🚎2-cov-wf] [![CI Style][🚎5-st-wfi]][🚎5-st-wf] [![CodeQL][🖐codeQL-img]][🖐codeQL] [![Apache SkyWalking Eyes License Compatibility Check][🚎15-🪪-wfi]][🚎15-🪪-wf]
44
13
 
45
14
  `if ci_badges.map(&:color).detect { it != "green"}` ☝️ [let me know][🖼️galtzo-discord], as I may have missed the [discord notification][🖼️galtzo-discord].
46
15
 
@@ -50,13 +19,20 @@
50
19
 
51
20
  [![OpenCollective Backers][🖇osc-backers-i]][🖇osc-backers] [![OpenCollective Sponsors][🖇osc-sponsors-i]][🖇osc-sponsors] [![Sponsor Me on Github][🖇sponsor-img]][🖇sponsor] [![Liberapay Goal Progress][⛳liberapay-img]][⛳liberapay] [![Donate on PayPal][🖇paypal-img]][🖇paypal] [![Buy me a coffee][🖇buyme-small-img]][🖇buyme] [![Donate on Polar][🖇polar-img]][🖇polar] [![Donate at ko-fi.com][🖇kofi-img]][🖇kofi]
52
21
 
22
+ <details>
23
+ <summary>👣 How will this project approach the September 2025 hostile takeover of RubyGems? 🚑️</summary>
24
+
25
+ I've summarized my thoughts in [this blog post](https://dev.to/galtzo/hostile-takeover-of-rubygems-my-thoughts-5hlo).
26
+
27
+ </details>
28
+
53
29
  ## 🌻 Synopsis
54
30
 
55
31
  OAuth 2.0 is the industry-standard protocol for authorization.
56
- OAuth 2.0 focuses on client developer simplicity while providing specific authorization flows for web applications,
57
- desktop applications, mobile phones, and living room devices.
58
32
  This is a RubyGem for implementing OAuth 2.0 clients (not servers) in Ruby applications.
59
33
 
34
+ ⭐️ including OAuth 2.1 draft spec & OpenID Connect (OIDC)
35
+
60
36
  ### Quick Examples
61
37
 
62
38
  <details markdown="1">
@@ -75,13 +51,14 @@ curl --request POST \
75
51
  NOTE: In the ruby version below, certain params are passed to the `get_token` call, instead of the client creation.
76
52
 
77
53
  ```ruby
78
- OAuth2::Client.new(
54
+ client = OAuth2::Client.new(
79
55
  "REDMOND_CLIENT_ID", # client_id
80
56
  "REDMOND_CLIENT_SECRET", # client_secret
81
57
  auth_scheme: :request_body, # Other modes are supported: :basic_auth, :tls_client_auth, :private_key_jwt
82
58
  token_url: "oauth2/token", # relative path, except with leading `/`, then absolute path
83
59
  site: "https://login.microsoftonline.com/REDMOND_REDACTED",
84
- ). # The base path for token_url when it is relative
60
+ )
61
+ client.
85
62
  client_credentials. # There are many other types to choose from!
86
63
  get_token(resource: "REDMOND_RESOURCE_UUID")
87
64
  ```
@@ -344,33 +321,44 @@ See [SECURITY.md][🔐security] and [IRP.md][🔐irp].
344
321
 
345
322
  ## ⚙️ Configuration
346
323
 
347
- You can turn on additional warnings.
324
+ Global settings for the library:
348
325
 
349
326
  ```ruby
350
327
  OAuth2.configure do |config|
351
- # Turn on a warning like:
352
- # OAuth2::AccessToken.from_hash: `hash` contained more than one 'token' key
353
328
  config.silence_extra_tokens_warning = false # default: true
354
- # Set to true if you want to also show warnings about no tokens
355
- config.silence_no_tokens_warning = false # default: true,
329
+ config.silence_no_tokens_warning = false # default: true
356
330
  end
357
331
  ```
358
332
 
359
- The "extra tokens" problem comes from ambiguity in the spec about which token is the right token.
360
- Some OAuth 2.0 standards legitimately have multiple tokens.
361
- You may need to subclass `OAuth2::AccessToken`, or write your own custom alternative to it, and pass it in.
362
- Specify your custom class with the `access_token_class` option.
333
+ Filtering-related settings:
363
334
 
364
- If you only need one token, you can, as of v2.0.10,
365
- specify the exact token name you want to extract via the `OAuth2::AccessToken` using
366
- the `token_name` option.
335
+ ```ruby
336
+ OAuth2.configure do |config|
337
+ config.filtered_label = "[REDACTED]" # default: "[FILTERED]"
338
+ config.filtered_debug_keys += ["client_assertion"]
339
+ end
340
+ ```
367
341
 
368
- You'll likely need to do some source diving.
369
- This gem has 100% test coverage for lines and branches, so the specs are a great place to look for ideas.
370
- If you have time and energy, please contribute to the documentation!
342
+ - `filtered_label` controls the placeholder used when sensitive values are filtered from inspected objects and debug logging output.
343
+ - `filtered_debug_keys` controls which key names have their values redacted from debug logging output when `OAUTH_DEBUG=true`.
344
+ - Debug logging remains opt-in and should still be used cautiously in production environments.
371
345
 
372
346
  ## 🔧 Basic Usage
373
347
 
348
+ ### Client Initialization Options
349
+
350
+ `OAuth2::Client.new` accepts several options:
351
+
352
+ - `:site`: The base URL for the OAuth 2.0 provider.
353
+ - `:authorize_url`: The authorization endpoint (default: `"oauth/authorize"`).
354
+ - `:token_url`: The token endpoint (default: `"oauth/token"`).
355
+ - `:auth_scheme`: The authentication scheme (`:basic_auth`, `:request_body`, `:tls_client_auth`, `:private_key_jwt`). Default is `:basic_auth`.
356
+ - `:connection_opts`: Options for the underlying Faraday connection (timeouts, proxy, etc.).
357
+ - `:raise_errors`: Whether to raise `OAuth2::Error` on 400+ responses (default: `true`).
358
+
359
+ <details markdown="1">
360
+ <summary><em>authorize_url</em> and <em>token_url</em></summary>
361
+
374
362
  ### `authorize_url` and `token_url` are on site root (Just Works!)
375
363
 
376
364
  ```ruby
@@ -416,6 +404,25 @@ client.class.name
416
404
  # => OAuth2::Client
417
405
  ```
418
406
 
407
+ </details>
408
+
409
+ ### Advanced Initializers
410
+
411
+ ```ruby
412
+ client = OAuth2::Client.new(id, secret, site: site) do |faraday|
413
+ faraday.request(:url_encoded)
414
+ faraday.adapter(:net_http_persistent)
415
+ end
416
+ ```
417
+
418
+ ### AccessToken Features
419
+
420
+ Instances of `OAuth2::AccessToken` handle request signing and token expiration.
421
+
422
+ - **Snake Case & Indifferent Access**: `response.parsed` returns a `SnakyHash` allowing access via string/symbol and snake_case keys even if the provider returns CamelCase.
423
+ - **Auto-Refresh**: You can manually check `token.expired?` and call `token.refresh`.
424
+ - **Serialization**: Persist tokens using `token.to_hash` and restore via `OAuth2::AccessToken.from_hash(client, hash)`.
425
+
419
426
  ### snake_case and indifferent access in Response#parsed
420
427
 
421
428
  ```ruby
@@ -553,6 +560,13 @@ ENV["OAUTH_DEBUG"] = "true"
553
560
  By default, debug output will go to `$stdout`. This can be overridden when
554
561
  initializing your OAuth2::Client.
555
562
 
563
+ Sensitive values are filtered from debug logging output using:
564
+
565
+ - `OAuth2.config[:filtered_label]`
566
+ - `OAuth2.config[:filtered_debug_keys]`
567
+
568
+ Debug logging remains opt-in and should still be used cautiously in production environments.
569
+
556
570
  ```ruby
557
571
  require "oauth2"
558
572
  client = OAuth2::Client.new(
@@ -565,15 +579,30 @@ client = OAuth2::Client.new(
565
579
 
566
580
  </details>
567
581
 
582
+ ### Request Target Trust Boundaries
583
+
584
+ This gem supports request flows that can involve absolute URLs in addition to relative paths.
585
+ That flexibility can expand trust boundaries when a token-bearing client is asked to send requests
586
+ to caller-provided targets.
587
+
588
+ Practical guidance:
589
+
590
+ - prefer relative paths where practical
591
+ - do not pass untrusted absolute URLs into token-bearing clients
592
+ - validate or allowlist request targets at the application layer today if your deployment has strict trust-boundary requirements
593
+
594
+ This release line does not yet enforce same-host or allowlist request policy automatically.
595
+ If stricter outbound request controls are needed, they should currently be implemented by the calling application.
596
+
568
597
  ### OAuth2::Response
569
598
 
570
599
  The `AccessToken` methods `#get`, `#post`, `#put` and `#delete` and the generic `#request`
571
- will return an instance of the #OAuth2::Response class.
600
+ will return an instance of the `OAuth2::Response` class.
572
601
 
573
602
  This instance contains a `#parsed` method that will parse the response body and
574
603
  return a Hash-like [`SnakyHash::StringKeyed`](https://gitlab.com/ruby-oauth/snaky_hash/-/blob/main/lib/snaky_hash/string_keyed.rb) if the `Content-Type` is `application/x-www-form-urlencoded` or if
575
- the body is a JSON object. It will return an Array if the body is a JSON
576
- array. Otherwise, it will return the original body string.
604
+ the body is a JSON object. It will return an Array if the body is a JSON
605
+ array. Otherwise, it will return the original body string.
577
606
 
578
607
  The original response body, headers, and status can be accessed via their
579
608
  respective methods.
@@ -615,16 +644,22 @@ Response instance will contain the `OAuth2::Error` instance.
615
644
 
616
645
  ### Authorization Grants
617
646
 
618
- Note on OAuth 2.1 (draft):
647
+ Currently, the Authorization Code, Implicit, Resource Owner Password Credentials, Client Credentials, and Assertion
648
+ authentication grant types have helper strategy classes that simplify client
649
+ use. They are available via the [`#auth_code`](https://gitlab.com/ruby-oauth/oauth2/-/blob/main/lib/oauth2/strategy/auth_code.rb),
650
+ [`#implicit`](https://gitlab.com/ruby-oauth/oauth2/-/blob/main/lib/oauth2/strategy/implicit.rb),
651
+ [`#password`](https://gitlab.com/ruby-oauth/oauth2/-/blob/main/lib/oauth2/strategy/password.rb),
652
+ [`#client_credentials`](https://gitlab.com/ruby-oauth/oauth2/-/blob/main/lib/oauth2/strategy/client_credentials.rb), and
653
+ [`#assertion`](https://gitlab.com/ruby-oauth/oauth2/-/blob/main/lib/oauth2/strategy/assertion.rb) methods respectively.
654
+
655
+ #### OAuth 2.1 (draft) Note:
619
656
 
620
- - PKCE is required for all OAuth clients using the authorization code flow (especially public clients). Implement PKCE in your app when required by your provider. See RFC 7636 and RFC 8252.
621
- - Redirect URIs must be compared using exact string matching by the Authorization Server.
622
- - The Implicit grant (response_type=token) and the Resource Owner Password Credentials grant are omitted from OAuth 2.1; they remain here for OAuth 2.0 compatibility but should be avoided for new apps.
623
- - Bearer tokens in the query string are omitted due to security risks; prefer Authorization header usage.
624
- - Refresh tokens for public clients must either be sender-constrained (e.g., DPoP/MTLS) or one-time use.
625
- - The definitions of public and confidential clients are simplified to refer only to whether the client has credentials.
657
+ - **PKCE** is required for all OAuth clients using the authorization code flow (especially public clients). Implement PKCE in your app when required by your provider. See RFC 7636 and RFC 8252.
658
+ - **Implicit grant** (response_type=token) and **Resource Owner Password Credentials grant** are omitted from OAuth 2.1; they remain here for OAuth 2.0 compatibility but should be avoided for new apps.
659
+ - **Redirect URIs** must be compared using exact string matching by the Authorization Server.
626
660
 
627
- References:
661
+ <details markdown="1">
662
+ <summary>OAuth 2.1 (draft) References</summary>
628
663
 
629
664
  - OAuth 2.1 draft: https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-13
630
665
  - Aaron Parecki: https://aaronparecki.com/2019/12/12/21/its-time-for-oauth-2-dot-1
@@ -633,13 +668,7 @@ References:
633
668
  - Video: https://www.youtube.com/watch?v=g_aVPdwBTfw
634
669
  - Differences overview: https://fusionauth.io/learn/expert-advice/oauth/differences-between-oauth-2-oauth-2-1/
635
670
 
636
- Currently, the Authorization Code, Implicit, Resource Owner Password Credentials, Client Credentials, and Assertion
637
- authentication grant types have helper strategy classes that simplify client
638
- use. They are available via the [`#auth_code`](https://gitlab.com/ruby-oauth/oauth2/-/blob/main/lib/oauth2/strategy/auth_code.rb),
639
- [`#implicit`](https://gitlab.com/ruby-oauth/oauth2/-/blob/main/lib/oauth2/strategy/implicit.rb),
640
- [`#password`](https://gitlab.com/ruby-oauth/oauth2/-/blob/main/lib/oauth2/strategy/password.rb),
641
- [`#client_credentials`](https://gitlab.com/ruby-oauth/oauth2/-/blob/main/lib/oauth2/strategy/client_credentials.rb), and
642
- [`#assertion`](https://gitlab.com/ruby-oauth/oauth2/-/blob/main/lib/oauth2/strategy/assertion.rb) methods respectively.
671
+ </details>
643
672
 
644
673
  These aren't full examples, but demonstrative of the differences between usage for each strategy.
645
674
 
@@ -774,7 +803,7 @@ Notes:
774
803
 
775
804
  </details>
776
805
 
777
- ### Instagram API (verb‑dependent token mode)
806
+ ### Verb‑dependent Token Mode
778
807
 
779
808
  Providers like Instagram require the access token to be sent differently depending on the HTTP verb:
780
809
 
@@ -783,6 +812,14 @@ Providers like Instagram require the access token to be sent differently dependi
783
812
 
784
813
  Since v2.0.15, you can configure an AccessToken with a verb‑dependent mode. The gem will choose how to send the token based on the request method.
785
814
 
815
+ Tips:
816
+
817
+ - Avoid query‑string bearer tokens unless required by your provider. Instagram explicitly requires it for `GET` requests.
818
+ - If you need a custom rule, you can pass a `Proc` for `mode`, e.g. `mode: ->(verb) { verb == :get ? :query : :header }`.
819
+
820
+ <details markdown="1">
821
+ <summary>Instagram API Example</summary>
822
+
786
823
  Example: exchanging and refreshing long‑lived Instagram tokens, and making API calls
787
824
 
788
825
  ```ruby
@@ -841,10 +878,7 @@ me = long_lived.get("/me", params: {fields: "id,username"}).parsed
841
878
  # long_lived.post("/me/media", body: {image_url: "https://...", caption: "hello"})
842
879
  ```
843
880
 
844
- Tips:
845
-
846
- - Avoid query‑string bearer tokens unless required by your provider. Instagram explicitly requires it for `GET` requests.
847
- - If you need a custom rule, you can pass a `Proc` for `mode`, e.g. `mode: ->(verb) { verb == :get ? :query : :header }`.
881
+ </details>
848
882
 
849
883
  ### Refresh Tokens
850
884
 
@@ -1085,11 +1119,12 @@ access = client.get_token({
1085
1119
  })
1086
1120
  ```
1087
1121
 
1088
- ### OpenID Connect (OIDC) Notes
1122
+ ### OpenID Connect (OIDC)
1089
1123
 
1090
- - If the token response includes an `id_token` (a JWT), this gem surfaces it but does not validate the signature. Use a JWT library and your provider's JWKs to verify it.
1091
- - For private_key_jwt client authentication, provide `auth_scheme: :private_key_jwt` and ensure your key configuration matches the provider requirements.
1092
- - See [OIDC.md](OIDC.md) for a more complete OIDC overview, example, and links to the relevant specifications.
1124
+ - If the token response includes an `id_token` (a JWT), this gem surfaces it in `token.params['id_token']`.
1125
+ - **Note**: This gem does **not** validate the signature of the `id_token`. You must use a JWT library (like the `jwt` [gem](https://github.com/jwt/ruby-jwt)) and your provider's JWKs to verify it.
1126
+ - For `private_key_jwt` client authentication, provide `auth_scheme: :private_key_jwt` and ensure your key configuration matches the provider requirements.
1127
+ - See [OIDC.md](OIDC.md) for a more complete OIDC overview and examples.
1093
1128
 
1094
1129
  ### Debugging
1095
1130
 
@@ -1139,6 +1174,10 @@ NOTE: [kettle-readme-backers][kettle-readme-backers] updates this list every day
1139
1174
 
1140
1175
  <!-- OPENCOLLECTIVE-ORGANIZATIONS:START -->
1141
1176
  No sponsors yet. Be the first!
1177
+
1178
+ ### Open Collective for Donors
1179
+
1180
+ [Bill Woika](https://opencollective.com/bill-woika)
1142
1181
  <!-- OPENCOLLECTIVE-ORGANIZATIONS:END -->
1143
1182
 
1144
1183
  [kettle-readme-backers]: https://github.com/ruby-oauth/oauth2/blob/main/exe/kettle-readme-backers
@@ -1257,7 +1296,7 @@ See [LICENSE.txt][📄license] for the official [Copyright Notice][📄copyright
1257
1296
 
1258
1297
  <ul>
1259
1298
  <li>
1260
- Copyright (c) 2017 – 2025 Peter H. Boling, of
1299
+ Copyright (c) 2017 – 2026 Peter H. Boling, of
1261
1300
  <a href="https://discord.gg/3qme4XHNKN">
1262
1301
  Galtzo.com
1263
1302
  <picture>
@@ -1384,8 +1423,6 @@ Thanks for RTFM. ☺️
1384
1423
  [📜gh-wiki-img]: https://img.shields.io/badge/wiki-examples-943CD2.svg?style=for-the-badge&logo=github&logoColor=white
1385
1424
  [👽dl-rank]: https://bestgems.org/gems/oauth2
1386
1425
  [👽dl-ranki]: https://img.shields.io/gem/rd/oauth2.svg
1387
- [👽oss-help]: https://www.codetriage.com/ruby-oauth/oauth2
1388
- [👽oss-helpi]: https://www.codetriage.com/ruby-oauth/oauth2/badges/users.svg
1389
1426
  [👽version]: https://bestgems.org/gems/oauth2
1390
1427
  [👽versioni]: https://img.shields.io/gem/v/oauth2.svg
1391
1428
  [🏀qlty-mnt]: https://qlty.sh/gh/ruby-oauth/projects/oauth2
@@ -1477,7 +1514,7 @@ Thanks for RTFM. ☺️
1477
1514
  [📌gitmoji]: https://gitmoji.dev
1478
1515
  [📌gitmoji-img]: https://img.shields.io/badge/gitmoji_commits-%20%F0%9F%98%9C%20%F0%9F%98%8D-34495e.svg?style=flat-square
1479
1516
  [🧮kloc]: https://www.youtube.com/watch?v=dQw4w9WgXcQ
1480
- [🧮kloc-img]: https://img.shields.io/badge/KLOC-0.526-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
1517
+ [🧮kloc-img]: https://img.shields.io/badge/KLOC-0.515-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
1481
1518
  [🔐security]: SECURITY.md
1482
1519
  [🔐security-img]: https://img.shields.io/badge/security-policy-259D6C.svg?style=flat
1483
1520
  [🔐irp]: IRP.md
data/REEK CHANGED
@@ -0,0 +1,2 @@
1
+ ./reek: 1: Error:: not found
2
+ ./reek: 2: Error:: not found
data/RUBOCOP.md CHANGED
File without changes
data/SECURITY.md CHANGED
@@ -12,7 +12,7 @@ To report a security vulnerability, please use the
12
12
  [Tidelift security contact](https://tidelift.com/security).
13
13
  Tidelift will coordinate the fix and disclosure.
14
14
 
15
- More detailed explanation of the process is in [IRP.md][IRP]
15
+ More detailed explanation of the process is in [IRP.md][IRP].
16
16
 
17
17
  ## Additional Support
18
18
 
data/THREAT_MODEL.md CHANGED
@@ -63,7 +63,16 @@ This document outlines the threat model for the `oauth2` Ruby gem, which impleme
63
63
  - Validate and sanitize all inputs
64
64
  - Use parameterized queries and safe APIs
65
65
 
66
- ### 5.7 Insufficient Logging and Monitoring
66
+ ### 5.7 Request-Target Trust Boundary Expansion
67
+ - **Threat:** Applications may pass untrusted or insufficiently validated absolute URLs into request paths that can carry OAuth credentials or authenticated state.
68
+ - **Risk:** This can expand trust boundaries, contributing to token leakage, authenticated requests to unintended hosts, or SSRF-like pivoting in the surrounding application.
69
+ - **Mitigations:**
70
+ - Prefer relative paths where practical
71
+ - Do not pass untrusted absolute URLs into token-bearing clients
72
+ - Validate or allowlist outbound request targets at the application layer
73
+ - Treat request-target validation as a separate concern from log redaction and token storage
74
+
75
+ ### 5.8 Insufficient Logging and Monitoring
67
76
  - **Threat:** Attacks go undetected
68
77
  - **Mitigations:**
69
78
  - Log security-relevant events (without sensitive data)
@@ -57,26 +57,23 @@ module OAuth2
57
57
  def from_hash(client, hash)
58
58
  fresh = hash.dup
59
59
  # If token_name is present, then use that key name
60
- key =
61
- if fresh.key?(:token_name)
62
- t_key = fresh[:token_name]
63
- no_tokens_warning(fresh, t_key)
64
- t_key
65
- else
66
- # Otherwise, if one of the supported default keys is present, use whichever has precedence
67
- supported_keys = TOKEN_KEY_LOOKUP & fresh.keys
68
- t_key = supported_keys[0]
69
- extra_tokens_warning(supported_keys, t_key)
70
- t_key
71
- end
60
+ if fresh.key?(:token_name)
61
+ t_key = fresh[:token_name]
62
+ no_tokens_warning(fresh, t_key)
63
+ else
64
+ # Otherwise, if one of the supported default keys is present, use whichever has precedence
65
+ supported_keys = TOKEN_KEY_LOOKUP & fresh.keys
66
+ t_key = supported_keys[0]
67
+ extra_tokens_warning(supported_keys, t_key)
68
+ end
72
69
  # :nocov:
73
70
  # TODO: Get rid of this branching logic when dropping Hashie < v3.2
74
71
  token = if !defined?(Hashie::VERSION) # i.e. <= "1.1.0"; the first Hashie to ship with a VERSION constant
75
72
  warn("snaky_hash and oauth2 will drop support for Hashie v0 in the next major version. Please upgrade to a modern Hashie.")
76
73
  # There is a bug in Hashie v0, which is accounts for.
77
- fresh.delete(key) || fresh[key] || ""
74
+ fresh.delete(t_key) || fresh[t_key] || ""
78
75
  else
79
- fresh.delete(key) || ""
76
+ fresh.delete(t_key) || ""
80
77
  end
81
78
  # :nocov:
82
79
  new(client, token, fresh)
@@ -51,13 +51,15 @@ module OAuth2
51
51
  end
52
52
  end
53
53
 
54
- # Encodes a Basic Authorization header value for the provided credentials.
55
- #
56
- # @param [String] user The client identifier
57
- # @param [String] password The client secret
58
- # @return [String] The value to use for the Authorization header
59
- def self.encode_basic_auth(user, password)
60
- "Basic #{Base64.strict_encode64("#{user}:#{password}")}"
54
+ class << self
55
+ # Encodes a Basic Authorization header value for the provided credentials.
56
+ #
57
+ # @param [String] user The client identifier
58
+ # @param [String] password The client secret
59
+ # @return [String] The value to use for the Authorization header
60
+ def encode_basic_auth(user, password)
61
+ "Basic #{Base64.strict_encode64("#{user}:#{password}")}"
62
+ end
61
63
  end
62
64
 
63
65
  private
data/lib/oauth2/client.rb CHANGED
@@ -42,7 +42,7 @@ module OAuth2
42
42
  # @option options [Hash] :connection_opts ({}) Hash of connection options to pass to initialize Faraday
43
43
  # @option options [Boolean] :raise_errors (true) whether to raise an OAuth2::Error on responses with 400+ status codes
44
44
  # @option options [Integer] :max_redirects (5) maximum number of redirects to follow
45
- # @option options [Logger] :logger (::Logger.new($stdout)) Logger instance for HTTP request/response output; requires OAUTH_DEBUG to be true
45
+ # @option options [Logger] :logger (::Logger.new($stdout)) Logger instance for HTTP request/response output; requires OAUTH_DEBUG to be true. When debug logging is enabled, sensitive values are filtered using {Auth::Sanitizer::SanitizedLogger} initialized from `OAuth2.config[:filtered_label]` and the key names in `OAuth2.config[:filtered_debug_keys]`.
46
46
  # @option options [Class] :access_token_class (AccessToken) class to use for access tokens; you can subclass OAuth2::AccessToken, @version 2.0+
47
47
  # @option options [Hash] :ssl SSL options for Faraday
48
48
  #
@@ -563,7 +563,15 @@ module OAuth2
563
563
  end
564
564
 
565
565
  def oauth_debug_logging(builder)
566
- builder.response(:logger, options[:logger], bodies: true) if OAuth2::OAUTH_DEBUG
566
+ builder.response(
567
+ :logger,
568
+ Auth::Sanitizer::SanitizedLogger.new(
569
+ options[:logger],
570
+ filtered_keys: OAuth2.config[:filtered_debug_keys],
571
+ label: OAuth2.config[:filtered_label],
572
+ ),
573
+ bodies: true,
574
+ ) if OAuth2::OAUTH_DEBUG
567
575
  end
568
576
  end
569
577
  end
data/lib/oauth2/error.rb CHANGED
@@ -17,6 +17,8 @@ module OAuth2
17
17
  # @param [OAuth2::Response, Hash, Object] response A Response or error payload
18
18
  def initialize(response)
19
19
  @response = response
20
+ @code = nil
21
+ @description = nil
20
22
  if response.respond_to?(:parsed)
21
23
  if response.parsed.is_a?(Hash)
22
24
  @code = response.parsed["error"]
@@ -1,52 +1,13 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module OAuth2
2
- # Mixin that redacts sensitive instance variables in #inspect output.
4
+ # Permanent alias for {Auth::Sanitizer::FilteredAttributes}.
3
5
  #
4
- # Classes include this module and declare which attributes should be filtered
5
- # using {.filtered_attributes}. Any instance variable name that includes one of
6
- # those attribute names will be shown as [FILTERED] in the object's inspect.
7
- module FilteredAttributes
8
- # Hook invoked when the module is included. Extends the including class with
9
- # class-level helpers.
10
- #
11
- # @param [Class] base The including class
12
- # @return [void]
13
- def self.included(base)
14
- base.extend(ClassMethods)
15
- end
16
-
17
- # Class-level helpers for configuring filtered attributes.
18
- module ClassMethods
19
- # Declare attributes that should be redacted in inspect output.
20
- #
21
- # @param [Array<Symbol, String>] attributes One or more attribute names
22
- # @return [void]
23
- def filtered_attributes(*attributes)
24
- @filtered_attribute_names = attributes.map(&:to_sym)
25
- end
26
-
27
- # The configured attribute names to filter.
28
- #
29
- # @return [Array<Symbol>]
30
- def filtered_attribute_names
31
- @filtered_attribute_names || []
32
- end
33
- end
34
-
35
- # Custom inspect that redacts configured attributes.
36
- #
37
- # @return [String]
38
- def inspect
39
- filtered_attribute_names = self.class.filtered_attribute_names
40
- return super if filtered_attribute_names.empty?
41
-
42
- inspected_vars = instance_variables.map do |var|
43
- if filtered_attribute_names.any? { |filtered_var| var.to_s.include?(filtered_var.to_s) }
44
- "#{var}=[FILTERED]"
45
- else
46
- "#{var}=#{instance_variable_get(var).inspect}"
47
- end
48
- end
49
- "#<#{self.class}:#{object_id} #{inspected_vars.join(", ")}>"
50
- end
51
- end
6
+ # This constant is intentionally kept in the `OAuth2` namespace because it
7
+ # was part of the public API before the implementation was extracted into the
8
+ # `auth-sanitizer` gem. It will **not** be deprecated or removed.
9
+ #
10
+ # New code that does not need the `OAuth2::` namespace can use
11
+ # {Auth::Sanitizer::FilteredAttributes} directly.
12
+ FilteredAttributes = Auth::Sanitizer::FilteredAttributes
52
13
  end
@@ -43,18 +43,20 @@ module OAuth2
43
43
  "text/plain" => :text,
44
44
  }
45
45
 
46
- # Adds a new content type parser.
47
- #
48
- # @param [Symbol] key A descriptive symbol key such as :json or :query
49
- # @param [Array<String>, String] mime_types One or more mime types to which this parser applies
50
- # @yield [String] Block that will be called to parse the response body
51
- # @yieldparam [String] body The response body to parse
52
- # @return [void]
53
- def self.register_parser(key, mime_types, &block)
54
- key = key.to_sym
55
- @@parsers[key] = block
56
- Array(mime_types).each do |mime_type|
57
- @@content_types[mime_type] = key
46
+ class << self
47
+ # Adds a new content type parser.
48
+ #
49
+ # @param [Symbol] key A descriptive symbol key such as :json or :query
50
+ # @param [Array<String>, String] mime_types One or more mime types to which this parser applies
51
+ # @yield [String] Block that will be called to parse the response body
52
+ # @yieldparam [String] body The response body to parse
53
+ # @return [void]
54
+ def register_parser(key, mime_types, &block)
55
+ key = key.to_sym
56
+ @@parsers[key] = block
57
+ Array(mime_types).each do |mime_type|
58
+ @@content_types[mime_type] = key
59
+ end
58
60
  end
59
61
  end
60
62
 
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -2,6 +2,6 @@
2
2
 
3
3
  module OAuth2
4
4
  module Version
5
- VERSION = "2.0.18"
5
+ VERSION = "2.0.19"
6
6
  end
7
7
  end
data/lib/oauth2.rb CHANGED
@@ -1,10 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # includes modules from stdlib
4
- require "cgi"
4
+ require "cgi/escape"
5
5
  require "time"
6
6
 
7
7
  # third party gems
8
+ require "auth/sanitizer"
8
9
  require "snaky_hash"
9
10
  require "version_gem"
10
11
 
@@ -43,38 +44,59 @@ module OAuth2
43
44
  # config[:silence_no_tokens_warning] = false
44
45
  # end
45
46
  #
47
+ # @example Customize filtered output markers and debug-log value filtering by key name
48
+ # OAuth2.configure do |config|
49
+ # config[:filtered_label] = "[REDACTED]"
50
+ # config[:filtered_debug_keys] += ["client_assertion"]
51
+ # end
52
+ #
53
+ # Existing objects and logger wrappers snapshot filtering configuration during
54
+ # initialization. Changing these config values later affects only newly
55
+ # initialized objects and debug loggers.
56
+ #
46
57
  # @return [SnakyHash::SymbolKeyed] A mutable Hash-like config with symbol keys
47
58
  DEFAULT_CONFIG = SnakyHash::SymbolKeyed.new(
48
59
  silence_extra_tokens_warning: true,
49
60
  silence_no_tokens_warning: true,
61
+ filtered_label: "[FILTERED]",
62
+ filtered_debug_keys: %w[
63
+ access_token
64
+ refresh_token
65
+ id_token
66
+ client_secret
67
+ assertion
68
+ code_verifier
69
+ token
70
+ ],
50
71
  )
51
72
 
52
73
  # The current runtime configuration for the library.
53
74
  #
54
75
  # @return [SnakyHash::SymbolKeyed]
55
- @config = DEFAULT_CONFIG.dup
76
+ CONFIG = DEFAULT_CONFIG.dup
56
77
 
57
78
  class << self
58
- # Access the current configuration.
79
+ def config
80
+ CONFIG
81
+ end
82
+
83
+ # Configure global library behavior.
59
84
  #
60
- # Prefer using {OAuth2.configure} to mutate configuration.
85
+ # Yields the mutable configuration object so callers can update settings.
61
86
  #
62
- # @return [SnakyHash::SymbolKeyed]
63
- attr_reader :config
87
+ # @yieldparam [SnakyHash::SymbolKeyed] config the configuration object
88
+ # @return [void]
89
+ def configure
90
+ yield config
91
+ end
64
92
  end
65
-
66
- # Configure global library behavior.
67
- #
68
- # Yields the mutable configuration object so callers can update settings.
69
- #
70
- # @yieldparam [SnakyHash::SymbolKeyed] config the configuration object
71
- # @return [void]
72
- def configure
73
- yield @config
74
- end
75
- module_function :configure
76
93
  end
77
94
 
95
+ # Wire Auth::Sanitizer's label provider to read from OAuth2.config so that
96
+ # FilteredAttributes-bearing objects and Auth::Sanitizer::SanitizedLogger instances
97
+ # pick up OAuth2.config[:filtered_label] at their initialization time.
98
+ Auth::Sanitizer.filtered_label_provider = -> { OAuth2.config[:filtered_label] }
99
+
78
100
  # Extend OAuth2::Version with VersionGem helpers to provide semantic version helpers.
79
101
  OAuth2::Version.class_eval do
80
102
  extend VersionGem::Basic
File without changes
File without changes
File without changes
data/sig/oauth2/error.rbs CHANGED
File without changes
@@ -1,6 +1,11 @@
1
1
  module OAuth2
2
2
  module FilteredAttributes
3
+ module InitializerMethods
4
+ def initialize: (*untyped args) { () -> untyped } -> untyped
5
+ end
6
+
3
7
  def self.included: (untyped) -> untyped
4
- def filtered_attributes: (*String) -> void
8
+ def filtered_attributes: (*(String | Symbol)) -> void
9
+ def thing_filter: () -> OAuth2::ThingFilter
5
10
  end
6
11
  end
File without changes
@@ -0,0 +1,32 @@
1
+ module OAuth2
2
+ class SanitizedLogger
3
+ def initialize: (untyped logger) -> void
4
+
5
+ def add: (untyped severity, ?untyped message, ?untyped progname) { () -> untyped } -> untyped
6
+ def <<: (String message) -> untyped
7
+ def debug: (?untyped progname) { () -> untyped } -> untyped
8
+ def info: (?untyped progname) { () -> untyped } -> untyped
9
+ def warn: (?untyped progname) { () -> untyped } -> untyped
10
+ def error: (?untyped progname) { () -> untyped } -> untyped
11
+ def fatal: (?untyped progname) { () -> untyped } -> untyped
12
+ def unknown: (?untyped progname) { () -> untyped } -> untyped
13
+ def close: () -> void
14
+ def formatter: () -> untyped
15
+ def formatter=: (untyped formatter) -> void
16
+ def level: () -> untyped
17
+ def level=: (untyped level) -> void
18
+ def progname: () -> untyped
19
+ def progname=: (untyped progname) -> void
20
+ def respond_to_missing?: (Symbol method_name, ?bool include_private) -> bool
21
+ def method_missing: (Symbol method_name, *untyped args) { () -> untyped } -> untyped
22
+
23
+ private
24
+
25
+ def log: (Symbol level, ?untyped progname) { () -> untyped } -> untyped
26
+ def sanitize: (untyped message) -> untyped
27
+ def thing_filter: () -> OAuth2::ThingFilter
28
+ def sanitize_authorization_header: (String message) -> String
29
+ def sanitize_json_pairs: (String message) -> String
30
+ def sanitize_form_and_query_pairs: (String message) -> String
31
+ end
32
+ end
File without changes
@@ -0,0 +1,10 @@
1
+ module OAuth2
2
+ class ThingFilter
3
+ attr_reader things: Array[String]
4
+ attr_reader label: String
5
+
6
+ def initialize: (Enumerable[untyped] things, label: String) -> void
7
+ def filtered?: (untyped thing_name) -> bool
8
+ def pattern_source: () -> String
9
+ end
10
+ end
File without changes
data/sig/oauth2.rbs CHANGED
File without changes
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: oauth2
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.18
4
+ version: 2.0.19
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter Boling
@@ -39,6 +39,20 @@ cert_chain:
39
39
  -----END CERTIFICATE-----
40
40
  date: 1980-01-02 00:00:00.000000000 Z
41
41
  dependencies:
42
+ - !ruby/object:Gem::Dependency
43
+ name: auth-sanitizer
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - "~>"
47
+ - !ruby/object:Gem::Version
48
+ version: '0.1'
49
+ type: :runtime
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - "~>"
54
+ - !ruby/object:Gem::Version
55
+ version: '0.1'
42
56
  - !ruby/object:Gem::Dependency
43
57
  name: faraday
44
58
  requirement: !ruby/object:Gem::Requirement
@@ -227,14 +241,14 @@ dependencies:
227
241
  requirements:
228
242
  - - "~>"
229
243
  - !ruby/object:Gem::Version
230
- version: '1.1'
244
+ version: '2.0'
231
245
  type: :development
232
246
  prerelease: false
233
247
  version_requirements: !ruby/object:Gem::Requirement
234
248
  requirements:
235
249
  - - "~>"
236
250
  - !ruby/object:Gem::Version
237
- version: '1.1'
251
+ version: '2.0'
238
252
  - !ruby/object:Gem::Dependency
239
253
  name: bundler-audit
240
254
  requirement: !ruby/object:Gem::Requirement
@@ -290,6 +304,9 @@ dependencies:
290
304
  - - "~>"
291
305
  - !ruby/object:Gem::Version
292
306
  version: '3.0'
307
+ - - ">="
308
+ - !ruby/object:Gem::Version
309
+ version: 3.0.6
293
310
  type: :development
294
311
  prerelease: false
295
312
  version_requirements: !ruby/object:Gem::Requirement
@@ -297,6 +314,9 @@ dependencies:
297
314
  - - "~>"
298
315
  - !ruby/object:Gem::Version
299
316
  version: '3.0'
317
+ - - ">="
318
+ - !ruby/object:Gem::Version
319
+ version: 3.0.6
300
320
  - !ruby/object:Gem::Dependency
301
321
  name: kettle-test
302
322
  requirement: !ruby/object:Gem::Requirement
@@ -306,7 +326,7 @@ dependencies:
306
326
  version: '1.0'
307
327
  - - ">="
308
328
  - !ruby/object:Gem::Version
309
- version: 1.0.6
329
+ version: 1.0.10
310
330
  type: :development
311
331
  prerelease: false
312
332
  version_requirements: !ruby/object:Gem::Requirement
@@ -316,7 +336,7 @@ dependencies:
316
336
  version: '1.0'
317
337
  - - ">="
318
338
  - !ruby/object:Gem::Version
319
- version: 1.0.6
339
+ version: 1.0.10
320
340
  - !ruby/object:Gem::Dependency
321
341
  name: ruby-progressbar
322
342
  requirement: !ruby/object:Gem::Requirement
@@ -340,7 +360,7 @@ dependencies:
340
360
  version: '1.0'
341
361
  - - ">="
342
362
  - !ruby/object:Gem::Version
343
- version: 1.0.2
363
+ version: 1.0.3
344
364
  type: :development
345
365
  prerelease: false
346
366
  version_requirements: !ruby/object:Gem::Requirement
@@ -350,7 +370,7 @@ dependencies:
350
370
  version: '1.0'
351
371
  - - ">="
352
372
  - !ruby/object:Gem::Version
353
- version: 1.0.2
373
+ version: 1.0.3
354
374
  - !ruby/object:Gem::Dependency
355
375
  name: gitmoji-regex
356
376
  requirement: !ruby/object:Gem::Requirement
@@ -447,17 +467,19 @@ files:
447
467
  - sig/oauth2/error.rbs
448
468
  - sig/oauth2/filtered_attributes.rbs
449
469
  - sig/oauth2/response.rbs
470
+ - sig/oauth2/sanitized_logger.rbs
450
471
  - sig/oauth2/strategy.rbs
472
+ - sig/oauth2/thing_filter.rbs
451
473
  - sig/oauth2/version.rbs
452
474
  homepage: https://github.com/ruby-oauth/oauth2
453
475
  licenses:
454
476
  - MIT
455
477
  metadata:
456
478
  homepage_uri: https://oauth2.galtzo.com/
457
- source_code_uri: https://github.com/ruby-oauth/oauth2/tree/v2.0.18
458
- changelog_uri: https://github.com/ruby-oauth/oauth2/blob/v2.0.18/CHANGELOG.md
479
+ source_code_uri: https://github.com/ruby-oauth/oauth2/tree/v2.0.19
480
+ changelog_uri: https://github.com/ruby-oauth/oauth2/blob/v2.0.19/CHANGELOG.md
459
481
  bug_tracker_uri: https://github.com/ruby-oauth/oauth2/issues
460
- documentation_uri: https://www.rubydoc.info/gems/oauth2/2.0.18
482
+ documentation_uri: https://www.rubydoc.info/gems/oauth2/2.0.19
461
483
  mailing_list_uri: https://groups.google.com/g/oauth-ruby
462
484
  funding_uri: https://github.com/sponsors/pboling
463
485
  wiki_uri: https://gitlab.com/ruby-oauth/oauth2/-/wiki
@@ -466,11 +488,11 @@ metadata:
466
488
  rubygems_mfa_required: 'true'
467
489
  post_install_message: |2
468
490
 
469
- ---+++--- oauth2 v2.0.18 ---+++---
491
+ ---+++--- oauth2 v2.0.19 ---+++---
470
492
 
471
493
  (minor) ⚠️ BREAKING CHANGES ⚠️ when upgrading from < v2
472
494
  • Summary of breaking changes: https://gitlab.com/ruby-oauth/oauth2#what-is-new-for-v20
473
- • Changes in this patch: https://gitlab.com/ruby-oauth/oauth2/-/blob/v2.0.18/CHANGELOG.md#2015-2025-09-08
495
+ • Changes in this patch: https://gitlab.com/ruby-oauth/oauth2/-/blob/v2.0.19/CHANGELOG.md#2015-2025-09-08
474
496
 
475
497
  News:
476
498
  1. New documentation website, including for OAuth 2.1 and OIDC: https://oauth2.galtzo.com
@@ -513,7 +535,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
513
535
  - !ruby/object:Gem::Version
514
536
  version: '0'
515
537
  requirements: []
516
- rubygems_version: 3.7.2
538
+ rubygems_version: 4.0.11
517
539
  specification_version: 4
518
540
  summary: "\U0001F510 OAuth 2.0, 2.1 & OIDC Core Ruby implementation"
519
541
  test_files: []
metadata.gz.sig CHANGED
Binary file