oauth2 2.0.14 → 2.0.16

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.
data/FUNDING.md CHANGED
@@ -18,11 +18,11 @@ Many paths lead to being a sponsor or a backer of this project. Are you on such
18
18
  [🖇sponsor]: https://github.com/sponsors/pboling
19
19
  [🖇polar-img]: https://img.shields.io/badge/polar-donate-a51611.svg?style=flat
20
20
  [🖇polar]: https://polar.sh/pboling
21
- [🖇kofi-img]: https://img.shields.io/badge/ko--fi-✓-a51611.svg?style=flat
21
+ [🖇kofi-img]: https://img.shields.io/badge/ko--fi-%E2%9C%93-a51611.svg?style=flat
22
22
  [🖇kofi]: https://ko-fi.com/O5O86SNP4
23
23
  [🖇patreon-img]: https://img.shields.io/badge/patreon-donate-a51611.svg?style=flat
24
24
  [🖇patreon]: https://patreon.com/galtzo
25
- [🖇buyme-small-img]: https://img.shields.io/badge/buy_me_a_coffee-✓-a51611.svg?style=flat
25
+ [🖇buyme-small-img]: https://img.shields.io/badge/buy_me_a_coffee-%E2%9C%93-a51611.svg?style=flat
26
26
  [🖇buyme]: https://www.buymeacoffee.com/pboling
27
27
  [🖇paypal-img]: https://img.shields.io/badge/donate-paypal-a51611.svg?style=flat&logo=paypal
28
28
  [🖇paypal]: https://www.paypal.com/paypalme/peterboling
data/README.md CHANGED
@@ -1,25 +1,25 @@
1
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]
2
2
 
3
- [🖼️oauth2-i]: https://logos.galtzo.com/assets/images/oauth/oauth2/avatar-192px.svg
4
- [🖼️oauth2]: https://github.com/ruby-oauth/oauth2
5
- [🖼️ruby-lang-i]: https://logos.galtzo.com/assets/images/ruby-lang/avatar-192px.svg
6
- [🖼️ruby-lang]: https://www.ruby-lang.org/
7
3
  [🖼️galtzo-i]: https://logos.galtzo.com/assets/images/galtzo-floss/avatar-192px.svg
8
4
  [🖼️galtzo-discord]: https://discord.gg/3qme4XHNKN
5
+ [🖼️ruby-lang-i]: https://logos.galtzo.com/assets/images/ruby-lang/avatar-192px.svg
6
+ [🖼️ruby-lang]: https://www.ruby-lang.org/
7
+ [🖼️oauth2-i]: https://logos.galtzo.com/assets/images/oauth/oauth2/avatar-192px.svg
8
+ [🖼️oauth2]: https://github.com/ruby-oauth/oauth2
9
9
 
10
10
  # 🔐 OAuth 2.0 Authorization Framework
11
11
 
12
12
  ⭐️ including OAuth 2.1 draft spec & OpenID Connect (OIDC)
13
13
 
14
- [![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] [![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 Truffle Ruby][🚎9-t-wfi]][🚎9-t-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 Caboose is an absolute WAGON][🚎13-cbs-wfi]][🚎13-cbs-wf] [![CI Test Coverage][🚎2-cov-wfi]][🚎2-cov-wf] [![CI Style][🚎5-st-wfi]][🚎5-st-wf] [![CodeQL][🖐codeQL-img]][🖐codeQL]
14
+ [![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] [![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 Truffle Ruby][🚎9-t-wfi]][🚎9-t-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]
15
15
 
16
- If ☝️ `ci_badges.map(&:color).detect { it != "green"}` [let me know][🖼️galtzo-discord], as I may have missed the [discord notification][🖼️galtzo-discord].
16
+ `if ci_badges.map(&:color).detect { it != "green"}` ☝️ [let me know][🖼️galtzo-discord], as I may have missed the [discord notification][🖼️galtzo-discord].
17
17
 
18
18
  ---
19
19
 
20
- OTOH, if `ci_badges.map(&:color).all? { it == "green"}` 👇️ send money so I can do more of this. FLOSS maintenance is now my full-time job.
20
+ `if ci_badges.map(&:color).all? { it == "green"}` 👇️ send money so I can do more of this. FLOSS maintenance is now my full-time job.
21
21
 
22
- [![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 to my FLOSS or refugee efforts at ko-fi.com][🖇kofi-img]][🖇kofi] [![Donate to my FLOSS or refugee efforts using Patreon][🖇patreon-img]][🖇patreon]
22
+ [![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]
23
23
 
24
24
  ## 🌻 Synopsis
25
25
 
@@ -28,7 +28,7 @@ OAuth 2.0 focuses on client developer simplicity while providing specific author
28
28
  desktop applications, mobile phones, and living room devices.
29
29
  This is a RubyGem for implementing OAuth 2.0 clients (not servers) in Ruby applications.
30
30
 
31
- ### Quick Example
31
+ ### Quick Examples
32
32
 
33
33
  <details>
34
34
  <summary>Convert the following `curl` command into a token request using this gem...</summary>
@@ -61,6 +61,61 @@ NOTE: `header` - The content type specified in the `curl` is already the default
61
61
 
62
62
  </details>
63
63
 
64
+ <details>
65
+ <summary>Complete E2E single file script against [navikt/mock-oauth2-server](https://github.com/navikt/mock-oauth2-server)</summary>
66
+
67
+ - E2E example using the mock test server added in v2.0.11
68
+
69
+ ```console
70
+ docker compose -f docker-compose-ssl.yml up -d --wait
71
+ ruby examples/e2e.rb
72
+ # If your machine is slow or Docker pulls are cold, increase the wait:
73
+ E2E_WAIT_TIMEOUT=120 ruby examples/e2e.rb
74
+ # The mock server serves HTTP on 8080; the example points to http://localhost:8080 by default.
75
+ ```
76
+
77
+ The output should be something like this:
78
+
79
+ ```console
80
+ ➜ ruby examples/e2e.rb
81
+ Access token (truncated): eyJraWQiOiJkZWZhdWx0...
82
+ userinfo status: 200
83
+ userinfo body: {"sub" => "demo-sub", "aud" => ["demo-aud"], "nbf" => 1757816758000, "iss" => "http://localhost:8080/default", "exp" => 1757820358000, "iat" => 1757816758000, "jti" => "d63b97a7-ebe5-4dea-93e6-d542caba6104"}
84
+ E2E complete
85
+ ```
86
+
87
+ Make sure to shut down the mock server when you are done:
88
+
89
+ ```console
90
+ docker compose -f docker-compose-ssl.yml down
91
+ ```
92
+
93
+ Troubleshooting: validate connectivity to the mock server
94
+
95
+ - Check container status and port mapping:
96
+ - docker compose -f docker-compose-ssl.yml ps
97
+ - From the host, try the discovery URL directly (this is what the example uses by default):
98
+ - curl -v http://localhost:8080/default/.well-known/openid-configuration
99
+ - If that fails immediately, also try: curl -v --connect-timeout 2 http://127.0.0.1:8080/default/.well-known/openid-configuration
100
+ - From inside the container (to distinguish container vs host networking):
101
+ - docker exec -it oauth2-mock-oauth2-server-1 curl -v http://127.0.0.1:8080/default/.well-known/openid-configuration
102
+ - Simple TCP probe from the host:
103
+ - nc -vz localhost 8080 # or: ruby -rsocket -e 'TCPSocket.new("localhost",8080).close; puts "tcp ok"'
104
+ - Inspect which host port 8080 is bound to (should be 8080):
105
+ - docker inspect -f '{{ (index (index .NetworkSettings.Ports "8080/tcp") 0).HostPort }}' oauth2-mock-oauth2-server-1
106
+ - Look at server logs for readiness/errors:
107
+ - docker logs -n 200 oauth2-mock-oauth2-server-1
108
+ - On Linux, ensure nothing else is bound to 8080 and that firewall/SELinux aren’t blocking:
109
+ - ss -ltnp | grep :8080
110
+
111
+ Notes
112
+ - Discovery URL pattern is: http://localhost:8080/<realm>/.well-known/openid-configuration, where <realm> defaults to "default".
113
+ - You can change these with env vars when running the example:
114
+ - E2E_ISSUER_BASE (default: http://localhost:8080)
115
+ - E2E_REALM (default: default)
116
+
117
+ </details>
118
+
64
119
  If it seems like you are in the wrong place, you might try one of these:
65
120
 
66
121
  * [OAuth 2.0 Spec][oauth2-spec]
@@ -73,27 +128,29 @@ If it seems like you are in the wrong place, you might try one of these:
73
128
 
74
129
  ## 💡 Info you can shake a stick at
75
130
 
76
- | Tokens to Remember | [![Gem name][⛳️name-img]][⛳️gem-name] [![Gem namespace][⛳️namespace-img]][⛳️gem-namespace] |
77
- |-------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
78
- | Works with JRuby | ![JRuby 9.1 Compat][💎jruby-9.1i] ![JRuby 9.2 Compat][💎jruby-9.2i] ![JRuby 9.3 Compat][💎jruby-9.3i] <br/> [![JRuby 9.4 Compat][💎jruby-9.4i]][🚎10-j-wf] [![JRuby 10.0 Compat][💎jruby-c-i]][🚎11-c-wf] [![JRuby HEAD Compat][💎jruby-headi]][🚎3-hd-wf] |
79
- | Works with Truffle Ruby | ![Truffle Ruby 22.3 Compat][💎truby-22.3i] ![Truffle Ruby 23.0 Compat][💎truby-23.0i] <br/> [![Truffle Ruby 23.1 Compat][💎truby-23.1i]][🚎9-t-wf] [![Truffle Ruby 24.1 Compat][💎truby-c-i]][🚎11-c-wf] |
80
- | Works with MRI Ruby 3 | [![Ruby 3.0 Compat][💎ruby-3.0i]][🚎4-lg-wf] [![Ruby 3.1 Compat][💎ruby-3.1i]][🚎6-s-wf] [![Ruby 3.2 Compat][💎ruby-3.2i]][🚎6-s-wf] [![Ruby 3.3 Compat][💎ruby-3.3i]][🚎6-s-wf] [![Ruby 3.4 Compat][💎ruby-c-i]][🚎11-c-wf] [![Ruby HEAD Compat][💎ruby-headi]][🚎3-hd-wf] |
81
- | Works with MRI Ruby 2 | ![Ruby 2.2 Compat][💎ruby-2.2i] <br/> [![Ruby 2.3 Compat][💎ruby-2.3i]][🚎1-an-wf] [![Ruby 2.4 Compat][💎ruby-2.4i]][🚎1-an-wf] [![Ruby 2.5 Compat][💎ruby-2.5i]][🚎1-an-wf] [![Ruby 2.6 Compat][💎ruby-2.6i]][🚎7-us-wf] [![Ruby 2.7 Compat][💎ruby-2.7i]][🚎7-us-wf] |
82
- | Source | [![Source on GitLab.com][📜src-gl-img]][📜src-gl] [![Source on CodeBerg.org][📜src-cb-img]][📜src-cb] [![Source on Github.com][📜src-gh-img]][📜src-gh] [![The best SHA: dQw4w9WgXcQ!][🧮kloc-img]][🧮kloc] |
83
- | Documentation | [![Discussion][⛳gg-discussions-img]][⛳gg-discussions] [![Current release on RubyDoc.info][📜docs-cr-rd-img]][🚎yard-current] [![YARD on Galtzo.com][📜docs-head-rd-img]][🚎yard-head] [![Maintainer Blog][🚂maint-blog-img]][🚂maint-blog] [![Wiki][📜wiki-img]][📜wiki] |
84
- | Compliance | [![License: MIT][📄license-img]][📄license-ref] [![📄ilo-declaration-img]][📄ilo-declaration] [![Security Policy][🔐security-img]][🔐security] [![Contributor Covenant 2.1][🪇conduct-img]][🪇conduct] [![SemVer 2.0.0][📌semver-img]][📌semver] |
85
- | Style | [![Enforced Code Style Linter][💎rlts-img]][💎rlts] [![Keep-A-Changelog 1.0.0][📗keep-changelog-img]][📗keep-changelog] [![Gitmoji Commits][📌gitmoji-img]][📌gitmoji] [![Compatibility appraised by: appraisal2][💎appraisal2-img]][💎appraisal2] |
86
- | Support | [![Live Chat on Discord][✉️discord-invite-img-ftb]][✉️discord-invite] [![Get help from me on Upwork][👨🏼‍🏫expsup-upwork-img]][👨🏼‍🏫expsup-upwork] [![Get help from me on Codementor][👨🏼‍🏫expsup-codementor-img]][👨🏼‍🏫expsup-codementor] |
87
- | Maintainer 🎖️ | [![Follow Me on LinkedIn][💖🖇linkedin-img]][💖🖇linkedin] [![Follow Me on Ruby.Social][💖🐘ruby-mast-img]][💖🐘ruby-mast] [![Follow Me on Bluesky][💖🦋bluesky-img]][💖🦋bluesky] [![Contact Maintainer][🚂maint-contact-img]][🚂maint-contact] [![My technical writing][💖💁🏼‍♂️devto-img]][💖💁🏼‍♂️devto] |
88
- | `...` 💖 | [![Find Me on WellFound:][💖✌️wellfound-img]][💖✌️wellfound] [![Find Me on CrunchBase][💖💲crunchbase-img]][💖💲crunchbase] [![My LinkTree][💖🌳linktree-img]][💖🌳linktree] [![More About Me][💖💁🏼‍♂️aboutme-img]][💖💁🏼‍♂️aboutme] [🧊][💖🧊berg] [🐙][💖🐙hub] [🛖][💖🛖hut] [🧪][💖🧪lab] |
131
+ | Tokens to Remember | [![Gem name][⛳️name-img]][⛳️gem-name] [![Gem namespace][⛳️namespace-img]][⛳️gem-namespace] |
132
+ |-------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
133
+ | Works with JRuby | ![JRuby 9.1 Compat][💎jruby-9.1i] ![JRuby 9.2 Compat][💎jruby-9.2i] ![JRuby 9.3 Compat][💎jruby-9.3i] <br/> [![JRuby 9.4 Compat][💎jruby-9.4i]][🚎10-j-wf] [![JRuby 10.0 Compat][💎jruby-c-i]][🚎11-c-wf] [![JRuby HEAD Compat][💎jruby-headi]][🚎3-hd-wf] |
134
+ | Works with Truffle Ruby | ![Truffle Ruby 22.3 Compat][💎truby-22.3i] ![Truffle Ruby 23.0 Compat][💎truby-23.0i] <br/> [![Truffle Ruby 23.1 Compat][💎truby-23.1i]][🚎9-t-wf] [![Truffle Ruby 24.1 Compat][💎truby-c-i]][🚎11-c-wf] |
135
+ | Works with MRI Ruby 3 | [![Ruby 3.0 Compat][💎ruby-3.0i]][🚎4-lg-wf] [![Ruby 3.1 Compat][💎ruby-3.1i]][🚎6-s-wf] [![Ruby 3.2 Compat][💎ruby-3.2i]][🚎6-s-wf] [![Ruby 3.3 Compat][💎ruby-3.3i]][🚎6-s-wf] [![Ruby 3.4 Compat][💎ruby-c-i]][🚎11-c-wf] [![Ruby HEAD Compat][💎ruby-headi]][🚎3-hd-wf] |
136
+ | Works with MRI Ruby 2 | ![Ruby 2.2 Compat][💎ruby-2.2i] <br/> [![Ruby 2.3 Compat][💎ruby-2.3i]][🚎1-an-wf] [![Ruby 2.4 Compat][💎ruby-2.4i]][🚎1-an-wf] [![Ruby 2.5 Compat][💎ruby-2.5i]][🚎1-an-wf] [![Ruby 2.6 Compat][💎ruby-2.6i]][🚎7-us-wf] [![Ruby 2.7 Compat][💎ruby-2.7i]][🚎7-us-wf] |
137
+ | Support & Community | [![Join Me on Daily.dev's RubyFriends][✉️ruby-friends-img]][✉️ruby-friends] [![Live Chat on Discord][✉️discord-invite-img-ftb]][✉️discord-invite] [![Get help from me on Upwork][👨🏼‍🏫expsup-upwork-img]][👨🏼‍🏫expsup-upwork] [![Get help from me on Codementor][👨🏼‍🏫expsup-codementor-img]][👨🏼‍🏫expsup-codementor] |
138
+ | Source | [![Source on GitLab.com][📜src-gl-img]][📜src-gl] [![Source on CodeBerg.org][📜src-cb-img]][📜src-cb] [![Source on Github.com][📜src-gh-img]][📜src-gh] [![The best SHA: dQw4w9WgXcQ!][🧮kloc-img]][🧮kloc] |
139
+ | Documentation | [![Discussion][⛳gg-discussions-img]][⛳gg-discussions] [![Current release on RubyDoc.info][📜docs-cr-rd-img]][🚎yard-current] [![YARD on Galtzo.com][📜docs-head-rd-img]][🚎yard-head] [![Maintainer Blog][🚂maint-blog-img]][🚂maint-blog] [![Wiki][📜wiki-img]][📜wiki] |
140
+ | Compliance | [![License: MIT][📄license-img]][📄license-ref] [![Compatible with Apache Software Projects: Verified by SkyWalking Eyes][📄license-compat-img]][📄license-compat] [![📄ilo-declaration-img]][📄ilo-declaration] [![Security Policy][🔐security-img]][🔐security] [![Contributor Covenant 2.1][🪇conduct-img]][🪇conduct] [![SemVer 2.0.0][📌semver-img]][📌semver] |
141
+ | Style | [![Enforced Code Style Linter][💎rlts-img]][💎rlts] [![Keep-A-Changelog 1.0.0][📗keep-changelog-img]][📗keep-changelog] [![Gitmoji Commits][📌gitmoji-img]][📌gitmoji] [![Compatibility appraised by: appraisal2][💎appraisal2-img]][💎appraisal2] |
142
+ | Maintainer 🎖️ | [![Follow Me on LinkedIn][💖🖇linkedin-img]][💖🖇linkedin] [![Follow Me on Ruby.Social][💖🐘ruby-mast-img]][💖🐘ruby-mast] [![Follow Me on Bluesky][💖🦋bluesky-img]][💖🦋bluesky] [![Contact Maintainer][🚂maint-contact-img]][🚂maint-contact] [![My technical writing][💖💁🏼‍♂️devto-img]][💖💁🏼‍♂️devto] |
143
+ | `...` 💖 | [![Find Me on WellFound:][💖✌️wellfound-img]][💖✌️wellfound] [![Find Me on CrunchBase][💖💲crunchbase-img]][💖💲crunchbase] [![My LinkTree][💖🌳linktree-img]][💖🌳linktree] [![More About Me][💖💁🏼‍♂️aboutme-img]][💖💁🏼‍♂️aboutme] [🧊][💖🧊berg] [🐙][💖🐙hub] [🛖][💖🛖hut] [🧪][💖🧪lab] |
89
144
 
90
145
  ### Compatibility
91
146
 
92
147
  * Operating Systems: Linux, MacOS, Windows
93
148
  * MRI Ruby @ v2.3, v2.4, v2.5, v2.6, v2.7, v3.0, v3.1, v3.2, v3.3, v3.4, HEAD
94
- * NOTE: This gem will still install on ruby v2.2, but vanilla GitHub Actions no longer supports testing against it, so YMMV.
95
- * JRuby @ v9.2, v9.3, v9.4, v10.0, HEAD
149
+ * NOTE: This gem may still _install_ and _run_ on ruby v2.2, but vanilla GitHub Actions no longer supports testing against it, so YMMV. Accept patches so long as they don't break the platforms that do run in CI.
150
+ * JRuby @ v9.4, v10.0, HEAD
151
+ * NOTE: This gem may still _install_ and _run_ on JRuby v9.2 and v9.3, but they are EOL, builds are flaky, and GitHub Actions [doesn't have][GHA-continue-on-error-ui] a proper [`allow-failures` feature][GHA-allow-failure], and until they do flaky EOL-platform builds get dropped, so YMMV. Accept patches so long as they don't break the platforms that do run in CI.
96
152
  * TruffleRuby @ v23.1, v24.1, HEAD
153
+ * NOTE: This gem may still _install_ and _run_ on Truffleruby v22.3 and v23.0, but they are EOL, builds are flaky, and GitHub Actions [doesn't have][GHA-continue-on-error-ui] a proper [`allow-failures` feature][GHA-allow-failure], and until they do flaky EOL-platform builds get dropped, so YMMV. Accept patches so long as they don't break the platforms that do run in CI.
97
154
  * gem `faraday` @ v0, v1, v2, HEAD ⏩️ [lostisland/faraday](https://github.com/lostisland/faraday)
98
155
  * gem `jwt` @ v1, v2, v3, HEAD ⏩️ [jwt/ruby-jwt](https://github.com/jwt/ruby-jwt)
99
156
  * gem `logger` @ v1.2, v1.5, v1.7, HEAD ⏩️ [ruby/logger](https://github.com/ruby/logger)
@@ -109,6 +166,9 @@ Also, where reasonable, tested against the runtime dependencies of those depende
109
166
 
110
167
  * gem `hashie` @ v0, v1, v2, v3, v4, v5, HEAD ⏩️ [hashie/hashie](https://github.com/hashie/hashie)
111
168
 
169
+ [GHA-continue-on-error-ui]: https://github.com/actions/runner/issues/2347#issuecomment-2653479732
170
+ [GHA-allow-failure]: https://github.com/orgs/community/discussions/15452
171
+
112
172
  #### Upgrading Runtime Gem Dependencies
113
173
 
114
174
  This project sits underneath a large portion of the authorization systems on the internet.
@@ -123,12 +183,12 @@ leading versions per each minor version of Ruby of all the runtime dependencies
123
183
 
124
184
  What does that mean specifically for the runtime dependencies?
125
185
 
126
- We have 100% test coverage of lines and branches, and this test suite runs across a large matrix
127
- covering the latest patch for each of the following minor versions:
186
+ We have 100% test coverage of lines and branches, and this test suite runs across a very large matrix.
187
+ It wouldn't be possible without appraisal2.
128
188
 
129
- | 🚚 _Amazing_ test matrix was brought to you by | 🔎 appraisal2 🔎 |
130
- |------------------------------------------------|--------------------------------------------------------------------------------------|
131
- | 👟 Check it out! | ✨ [github.com/appraisal-rb/appraisal2](https://github.com/appraisal-rb/appraisal2) ✨ |
189
+ | 🚚 _Amazing_ test matrix was brought to you by | 🔎 appraisal2 🔎 and the color 💚 green 💚 |
190
+ |------------------------------------------------|--------------------------------------------------------|
191
+ | 👟 Check it out! | ✨ [github.com/appraisal-rb/appraisal2][💎appraisal2] ✨ |
132
192
 
133
193
  #### You should upgrade this gem with confidence\*.
134
194
 
@@ -138,7 +198,7 @@ covering the latest patch for each of the following minor versions:
138
198
  - You should upgrade the dependencies of this gem with confidence\*.
139
199
  - Please do upgrade, and then, when it goes smooth as butter [please sponsor me][🖇sponsor]. Thanks!
140
200
 
141
- [sv-pub-api]: #-is-platform-support-part-of-the-public-api
201
+ [sv-pub-api]: #-versioning
142
202
 
143
203
  \* MIT license; The only guarantees I make are for [enterprise support](#enterprise-support).
144
204
 
@@ -160,7 +220,7 @@ If you use a gem version of a core Ruby library it should work fine!
160
220
  ### Federated DVCS
161
221
 
162
222
  <details>
163
- <summary>Find this repo on other forges (Coming soon!)</summary>
223
+ <summary>Find this repo on other forges</summary>
164
224
 
165
225
  | Federated [DVCS][💎d-in-dvcs] Repository | Status | Issues | PRs | Wiki | CI | Discussions |
166
226
  |-----------------------------------------------|-----------------------------------------------------------------------|---------------------------|--------------------------|---------------------------|--------------------------|------------------------------|
@@ -678,6 +738,18 @@ using various class methods including the standard new, `from_hash` (if you have
678
738
  a hash of the values), or `from_kvform` (if you have an
679
739
  `application/x-www-form-urlencoded` encoded string of the values).
680
740
 
741
+ Options (since v2.0.x unless noted):
742
+ - expires_latency (Integer | nil): Seconds to subtract from expires_in when computing #expired? to offset latency.
743
+ - token_name (String | Symbol | nil): When multiple token-like fields exist in responses, select the field name to use as the access token (since v2.0.10).
744
+ - mode (Symbol | Proc | Hash): Controls how the token is transmitted on requests made via this AccessToken instance.
745
+ - :header — Send as Authorization: Bearer <token> header (default and preferred by OAuth 2.1 draft guidance).
746
+ - :query — Send as access_token query parameter (discouraged in general, but required by some providers).
747
+ - Verb-dependent (since v2.0.15): Provide either:
748
+ - a Proc taking |verb| and returning :header or :query, or
749
+ - a Hash with verb symbols as keys, for example: {get: :query, post: :header, delete: :header}.
750
+
751
+ Note: Verb-dependent mode was added in v2.0.15 to support providers like Instagram that require query mode for GET and header mode for POST/DELETE.
752
+
681
753
  ### OAuth2::Error
682
754
 
683
755
  On 400+ status code responses, an `OAuth2::Error` will be raised. If it is a
@@ -847,6 +919,76 @@ Notes:
847
919
 
848
920
  </details>
849
921
 
922
+ ### Instagram API (verb‑dependent token mode)
923
+
924
+ Providers like Instagram require the access token to be sent differently depending on the HTTP verb:
925
+ - GET requests: token must be in the query string (?access_token=...)
926
+ - POST/DELETE requests: token must be in the Authorization header (Bearer ...)
927
+
928
+ 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.
929
+
930
+ Example: exchanging and refreshing long‑lived Instagram tokens, and making API calls
931
+
932
+ ```ruby
933
+ require "oauth2"
934
+
935
+ # NOTE: Users authenticate via Facebook Login to obtain a short‑lived user token (not shown here).
936
+ # See Facebook Login docs for obtaining the initial short‑lived token.
937
+
938
+ client = OAuth2::Client.new(nil, nil, site: "https://graph.instagram.com")
939
+
940
+ # Start with a short‑lived token you already obtained via Facebook Login
941
+ short_lived = OAuth2::AccessToken.new(
942
+ client,
943
+ ENV["IG_SHORT_LIVED_TOKEN"],
944
+ # Key part: verb‑dependent mode
945
+ mode: {get: :query, post: :header, delete: :header},
946
+ )
947
+
948
+ # 1) Exchange for a long‑lived token (Instagram requires GET with access_token in query)
949
+ # Endpoint: GET https://graph.instagram.com/access_token
950
+ # Params: grant_type=ig_exchange_token, client_secret=APP_SECRET
951
+ exchange = short_lived.get(
952
+ "/access_token",
953
+ params: {
954
+ grant_type: "ig_exchange_token",
955
+ client_secret: ENV["IG_APP_SECRET"],
956
+ # access_token param will be added automatically by the AccessToken (mode => :query for GET)
957
+ },
958
+ )
959
+ long_lived_token_value = exchange.parsed["access_token"]
960
+
961
+ long_lived = OAuth2::AccessToken.new(
962
+ client,
963
+ long_lived_token_value,
964
+ mode: {get: :query, post: :header, delete: :header},
965
+ )
966
+
967
+ # 2) Refresh the long‑lived token (Instagram uses GET with token in query)
968
+ # Endpoint: GET https://graph.instagram.com/refresh_access_token
969
+ refresh_resp = long_lived.get(
970
+ "/refresh_access_token",
971
+ params: {grant_type: "ig_refresh_token"},
972
+ )
973
+ long_lived = OAuth2::AccessToken.new(
974
+ client,
975
+ refresh_resp.parsed["access_token"],
976
+ mode: {get: :query, post: :header, delete: :header},
977
+ )
978
+
979
+ # 3) Typical API GET request (token in query automatically)
980
+ me = long_lived.get("/me", params: {fields: "id,username"}).parsed
981
+
982
+ # 4) Example POST (token sent via Bearer header automatically)
983
+ # Note: Replace the path/params with a real Instagram Graph API POST you need,
984
+ # such as publishing media via the Graph API endpoints.
985
+ # long_lived.post("/me/media", body: {image_url: "https://...", caption: "hello"})
986
+ ```
987
+
988
+ Tips:
989
+ - Avoid query‑string bearer tokens unless required by your provider. Instagram explicitly requires it for GET.
990
+ - If you need a custom rule, you can pass a Proc for mode, e.g. mode: ->(verb) { verb == :get ? :query : :header }.
991
+
850
992
  ### Refresh Tokens
851
993
 
852
994
  When the server issues a refresh_token, you can refresh manually or implement an auto-refresh wrapper.
@@ -1279,7 +1421,7 @@ To join the community or get help 👇️ Join the Discord.
1279
1421
 
1280
1422
  [![Live Chat on Discord][✉️discord-invite-img-ftb]][✉️discord-invite]
1281
1423
 
1282
- To say "thanks for maintaining such a great tool" ☝️ Join the Discord or 👇️ send money.
1424
+ To say "thanks!" ☝️ Join the Discord or 👇️ send money.
1283
1425
 
1284
1426
  [![Sponsor ruby-oauth/oauth2 on Open Source Collective][🖇osc-all-bottom-img]][🖇osc] 💌 [![Sponsor me on GitHub Sponsors][🖇sponsor-bottom-img]][🖇sponsor] 💌 [![Sponsor me on Liberapay][⛳liberapay-bottom-img]][⛳liberapay-img] 💌 [![Donate on PayPal][🖇paypal-bottom-img]][🖇paypal-img]
1285
1427
 
@@ -1306,11 +1448,11 @@ Thanks for RTFM. ☺️
1306
1448
  [🖇sponsor]: https://github.com/sponsors/pboling
1307
1449
  [🖇polar-img]: https://img.shields.io/badge/polar-donate-a51611.svg?style=flat
1308
1450
  [🖇polar]: https://polar.sh/pboling
1309
- [🖇kofi-img]: https://img.shields.io/badge/ko--fi-✓-a51611.svg?style=flat
1451
+ [🖇kofi-img]: https://img.shields.io/badge/ko--fi-%E2%9C%93-a51611.svg?style=flat
1310
1452
  [🖇kofi]: https://ko-fi.com/O5O86SNP4
1311
1453
  [🖇patreon-img]: https://img.shields.io/badge/patreon-donate-a51611.svg?style=flat
1312
1454
  [🖇patreon]: https://patreon.com/galtzo
1313
- [🖇buyme-small-img]: https://img.shields.io/badge/buy_me_a_coffee-✓-a51611.svg?style=flat
1455
+ [🖇buyme-small-img]: https://img.shields.io/badge/buy_me_a_coffee-%E2%9C%93-a51611.svg?style=flat
1314
1456
  [🖇buyme-img]: https://img.buymeacoffee.com/button-api/?text=Buy%20me%20a%20latte&emoji=&slug=pboling&button_colour=FFDD00&font_colour=000000&font_family=Cookie&outline_colour=000000&coffee_colour=ffffff
1315
1457
  [🖇buyme]: https://www.buymeacoffee.com/pboling
1316
1458
  [🖇paypal-img]: https://img.shields.io/badge/donate-paypal-a51611.svg?style=flat&logo=paypal
@@ -1319,7 +1461,9 @@ Thanks for RTFM. ☺️
1319
1461
  [🖇floss-funding.dev]: https://floss-funding.dev
1320
1462
  [🖇floss-funding-gem]: https://github.com/galtzo-floss/floss_funding
1321
1463
  [✉️discord-invite]: https://discord.gg/3qme4XHNKN
1322
- [✉️discord-invite-img-ftb]: https://img.shields.io/discord/1373797679469170758?style=for-the-badge
1464
+ [✉️discord-invite-img-ftb]: https://img.shields.io/discord/1373797679469170758?style=for-the-badge&logo=discord
1465
+ [✉️ruby-friends-img]: https://img.shields.io/badge/daily.dev-%F0%9F%92%8E_Ruby_Friends-0A0A0A?style=for-the-badge&logo=dailydotdev&logoColor=white
1466
+ [✉️ruby-friends]: https://app.daily.dev/squads/rubyfriends
1323
1467
 
1324
1468
  [⛳gg-discussions]: https://groups.google.com/g/oauth-ruby
1325
1469
  [⛳gg-discussions-img]: https://img.shields.io/badge/google-group-0093D0.svg?style=for-the-badge&logo=google&logoColor=orange
@@ -1342,7 +1486,7 @@ Thanks for RTFM. ☺️
1342
1486
  [💖💲crunchbase]: https://www.crunchbase.com/person/peter-boling
1343
1487
  [💖💲crunchbase-img]: https://img.shields.io/badge/peter--boling-purple?style=flat&logo=crunchbase
1344
1488
  [💖🐘ruby-mast]: https://ruby.social/@galtzo
1345
- [💖🐘ruby-mast-img]: https://img.shields.io/mastodon/follow/109447111526622197?domain=https%3A%2F%2Fruby.social&style=flat&logo=mastodon&label=Ruby%20%40galtzo
1489
+ [💖🐘ruby-mast-img]: https://img.shields.io/mastodon/follow/109447111526622197?domain=https://ruby.social&style=flat&logo=mastodon&label=Ruby%20@galtzo
1346
1490
  [💖🦋bluesky]: https://bsky.app/profile/galtzo.com
1347
1491
  [💖🦋bluesky-img]: https://img.shields.io/badge/@galtzo.com-0285FF?style=flat&logo=bluesky&logoColor=white
1348
1492
  [💖🌳linktree]: https://linktr.ee/galtzo
@@ -1412,14 +1556,16 @@ Thanks for RTFM. ☺️
1412
1556
  [🚎10-j-wfi]: https://github.com/ruby-oauth/oauth2/actions/workflows/jruby.yml/badge.svg
1413
1557
  [🚎11-c-wf]: https://github.com/ruby-oauth/oauth2/actions/workflows/current.yml
1414
1558
  [🚎11-c-wfi]: https://github.com/ruby-oauth/oauth2/actions/workflows/current.yml/badge.svg
1415
- [🚎12-crh-wf]: https://github.com/ruby-oauth/oauth2/actions/workflows/current-runtime-heads.yml
1416
- [🚎12-crh-wfi]: https://github.com/ruby-oauth/oauth2/actions/workflows/current-runtime-heads.yml/badge.svg
1559
+ [🚎12-crh-wf]: https://github.com/ruby-oauth/oauth2/actions/workflows/dep-heads.yml
1560
+ [🚎12-crh-wfi]: https://github.com/ruby-oauth/oauth2/actions/workflows/dep-heads.yml/badge.svg
1417
1561
  [🚎13-cbs-wf]: https://github.com/ruby-oauth/oauth2/actions/workflows/caboose.yml
1418
1562
  [🚎13-cbs-wfi]: https://github.com/ruby-oauth/oauth2/actions/workflows/caboose.yml/badge.svg
1419
1563
  [🚎13-🔒️-wf]: https://github.com/ruby-oauth/oauth2/actions/workflows/locked_deps.yml
1420
1564
  [🚎13-🔒️-wfi]: https://github.com/ruby-oauth/oauth2/actions/workflows/locked_deps.yml/badge.svg
1421
1565
  [🚎14-🔓️-wf]: https://github.com/ruby-oauth/oauth2/actions/workflows/unlocked_deps.yml
1422
1566
  [🚎14-🔓️-wfi]: https://github.com/ruby-oauth/oauth2/actions/workflows/unlocked_deps.yml/badge.svg
1567
+ [🚎15-🪪-wf]: https://github.com/ruby-oauth/oauth2/actions/workflows/license-eye.yml
1568
+ [🚎15-🪪-wfi]: https://github.com/ruby-oauth/oauth2/actions/workflows/license-eye.yml/badge.svg
1423
1569
  [💎ruby-2.2i]: https://img.shields.io/badge/Ruby-2.2_(%F0%9F%9A%ABCI)-AABBCC?style=for-the-badge&logo=ruby&logoColor=white
1424
1570
  [💎ruby-2.3i]: https://img.shields.io/badge/Ruby-2.3-DF00CA?style=for-the-badge&logo=ruby&logoColor=white
1425
1571
  [💎ruby-2.4i]: https://img.shields.io/badge/Ruby-2.4-DF00CA?style=for-the-badge&logo=ruby&logoColor=white
@@ -1467,15 +1613,17 @@ Thanks for RTFM. ☺️
1467
1613
  [📗keep-changelog]: https://keepachangelog.com/en/1.0.0/
1468
1614
  [📗keep-changelog-img]: https://img.shields.io/badge/keep--a--changelog-1.0.0-34495e.svg?style=flat
1469
1615
  [📌gitmoji]:https://gitmoji.dev
1470
- [📌gitmoji-img]:https://img.shields.io/badge/gitmoji_commits-%20😜%20😍-34495e.svg?style=flat-square
1616
+ [📌gitmoji-img]:https://img.shields.io/badge/gitmoji_commits-%20%F0%9F%98%9C%20%F0%9F%98%8D-34495e.svg?style=flat-square
1471
1617
  [🧮kloc]: https://www.youtube.com/watch?v=dQw4w9WgXcQ
1472
- [🧮kloc-img]: https://img.shields.io/badge/KLOC-0.519-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
1618
+ [🧮kloc-img]: https://img.shields.io/badge/KLOC-0.409-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
1473
1619
  [🔐security]: SECURITY.md
1474
1620
  [🔐security-img]: https://img.shields.io/badge/security-policy-259D6C.svg?style=flat
1475
1621
  [📄copyright-notice-explainer]: https://opensource.stackexchange.com/questions/5778/why-do-licenses-such-as-the-mit-license-specify-a-single-year
1476
1622
  [📄license]: LICENSE.txt
1477
1623
  [📄license-ref]: https://opensource.org/licenses/MIT
1478
1624
  [📄license-img]: https://img.shields.io/badge/License-MIT-259D6C.svg
1625
+ [📄license-compat]: https://dev.to/galtzo/how-to-check-license-compatibility-41h0
1626
+ [📄license-compat-img]: https://img.shields.io/badge/Apache_Compatible:_Category_A-%E2%9C%93-259D6C.svg?style=flat&logo=Apache
1479
1627
  [📄ilo-declaration]: https://www.ilo.org/declaration/lang--en/index.htm
1480
1628
  [📄ilo-declaration-img]: https://img.shields.io/badge/ILO_Fundamental_Principles-✓-259D6C.svg?style=flat
1481
1629
  [🚎yard-current]: http://rubydoc.info/gems/oauth2
@@ -1483,7 +1631,7 @@ Thanks for RTFM. ☺️
1483
1631
  [💎stone_checksums]: https://github.com/galtzo-floss/stone_checksums
1484
1632
  [💎SHA_checksums]: https://gitlab.com/ruby-oauth/oauth2/-/tree/main/checksums
1485
1633
  [💎rlts]: https://github.com/rubocop-lts/rubocop-lts
1486
- [💎rlts-img]: https://img.shields.io/badge/code_style_%26_linting-rubocop--lts-34495e.svg?plastic&logo=ruby&logoColor=white
1634
+ [💎rlts-img]: https://img.shields.io/badge/code_style_&_linting-rubocop--lts-34495e.svg?plastic&logo=ruby&logoColor=white
1487
1635
  [💎appraisal2]: https://github.com/appraisal-rb/appraisal2
1488
1636
  [💎appraisal2-img]: https://img.shields.io/badge/appraised_by-appraisal2-34495e.svg?plastic&logo=ruby&logoColor=white
1489
1637
  [💎d-in-dvcs]: https://railsbling.com/posts/dvcs/put_the_d_in_dvcs/
@@ -1493,8 +1641,8 @@ Thanks for RTFM. ☺️
1493
1641
  rel="me" Social Proofs
1494
1642
  </summary>
1495
1643
 
1496
- <a rel="me" alt="Follow me on Ruby.social" href="https://ruby.social/@galtzo"><img src="https://img.shields.io/mastodon/follow/109447111526622197?domain=https%3A%2F%2Fruby.social&style=social&label=Follow%20%40galtzo%20on%20Ruby.social"></a>
1497
- <a rel="me" alt="Follow me on FLOSS.social" href="https://floss.social/@galtzo"><img src="https://img.shields.io/mastodon/follow/110304921404405715?domain=https%3A%2F%2Ffloss.social&style=social&label=Follow%20%40galtzo%20on%20Floss.social"></a>
1644
+ <a rel="me" alt="Follow me on Ruby.social" href="https://ruby.social/@galtzo"><img src="https://img.shields.io/mastodon/follow/109447111526622197?domain=https://ruby.social&style=social&label=Follow%20@galtzo%20on%20Ruby.social"></a>
1645
+ <a rel="me" alt="Follow me on FLOSS.social" href="https://floss.social/@galtzo"><img src="https://img.shields.io/mastodon/follow/110304921404405715?domain=https://floss.social&style=social&label=Follow%20@galtzo%20on%20Floss.social"></a>
1498
1646
 
1499
1647
  </details>
1500
1648
 
data/SECURITY.md CHANGED
@@ -2,15 +2,9 @@
2
2
 
3
3
  ## Supported Versions
4
4
 
5
- | Version | Supported | Post-EOL / Enterprise |
6
- |----------|-----------|---------------------------------------|
7
- | 2.latest | ✅ | [Tidelift Subscription][tidelift-ref] |
8
- | 1.latest | ✅ | [Tidelift Subscription][tidelift-ref] |
9
- | <= 1 | ⛔ | ⛔ |
10
-
11
- ### EOL Policy
12
-
13
- Non-commercial support for the oldest version of Ruby (which itself is going EOL) will be dropped each year in April.
5
+ | Version | Supported |
6
+ |----------|-----------|
7
+ | 1.latest | ✅ |
14
8
 
15
9
  ## Security contact information
16
10
 
@@ -25,11 +19,3 @@ please consider sponsoring the project / maintainer @ https://liberapay.com/pbol
25
19
  or find other sponsorship links in the [README].
26
20
 
27
21
  [README]: README.md
28
-
29
- ## Enterprise Support
30
-
31
- Available as part of the Tidelift Subscription.
32
-
33
- The maintainers of this library and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source packages you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact packages you use. [Learn more.][tidelift-ref]
34
-
35
- [tidelift-ref]: https://tidelift.com/subscription/pkg/rubygems-oauth2?utm_source=rubygems-oauth2&utm_medium=referral&utm_campaign=enterprise&utm_term=repo
@@ -132,8 +132,9 @@ You may need to set `snaky: false`. See inline documentation for more info.
132
132
  # @option opts [FixNum, String] :expires_in (nil) the number of seconds in which the AccessToken will expire
133
133
  # @option opts [FixNum, String] :expires_at (nil) the epoch time in seconds in which AccessToken will expire
134
134
  # @option opts [FixNum, String] :expires_latency (nil) the number of seconds by which AccessToken validity will be reduced to offset latency, @version 2.0+
135
- # @option opts [Symbol] :mode (:header) the transmission mode of the Access Token parameter value
136
- # one of :header, :body or :query
135
+ # @option opts [Symbol or callable] :mode (:header) the transmission mode of the Access Token parameter value:
136
+ # either one of :header, :body or :query, or a callable that accepts a request-verb parameter
137
+ # and returns one of these three symbols.
137
138
  # @option opts [String] :header_format ('Bearer %s') the string format to use for the Authorization header
138
139
  # @option opts [String] :param_name ('access_token') the parameter name to use for transmission of the
139
140
  # Access Token value in :body or :query transmission mode
@@ -324,7 +325,7 @@ You may need to set `snaky: false`. See inline documentation for more info.
324
325
  #
325
326
  # @see OAuth2::Client#request
326
327
  def request(verb, path, opts = {}, &block)
327
- configure_authentication!(opts)
328
+ configure_authentication!(opts, verb)
328
329
  @client.request(verb, path, opts, &block)
329
330
  end
330
331
 
@@ -370,8 +371,9 @@ You may need to set `snaky: false`. See inline documentation for more info.
370
371
 
371
372
  private
372
373
 
373
- def configure_authentication!(opts)
374
- case options[:mode]
374
+ def configure_authentication!(opts, verb)
375
+ mode = options[:mode].respond_to?(:call) ? options[:mode].call(verb) : options[:mode]
376
+ case mode
375
377
  when :header
376
378
  opts[:headers] ||= {}
377
379
  opts[:headers].merge!(headers)
@@ -389,7 +391,7 @@ You may need to set `snaky: false`. See inline documentation for more info.
389
391
  end
390
392
  # @todo support for multi-part (file uploads)
391
393
  else
392
- raise("invalid :mode option of #{options[:mode]}")
394
+ raise("invalid :mode option of #{mode}")
393
395
  end
394
396
  end
395
397
 
@@ -2,6 +2,6 @@
2
2
 
3
3
  module OAuth2
4
4
  module Version
5
- VERSION = "2.0.14"
5
+ VERSION = "2.0.16"
6
6
  end
7
7
  end
data.tar.gz.sig CHANGED
Binary file