oauth2 2.0.17 → 2.0.18

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/README.md CHANGED
@@ -1,3 +1,32 @@
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
+
1
30
  [![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
31
 
3
32
  [🖼️galtzo-i]: https://logos.galtzo.com/assets/images/galtzo-floss/avatar-192px.svg
@@ -11,7 +40,7 @@
11
40
 
12
41
  ⭐️ including OAuth 2.1 draft spec & OpenID Connect (OIDC)
13
42
 
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] [![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 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]
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]
15
44
 
16
45
  `if ci_badges.map(&:color).detect { it != "green"}` ☝️ [let me know][🖼️galtzo-discord], as I may have missed the [discord notification][🖼️galtzo-discord].
17
46
 
@@ -30,7 +59,7 @@ This is a RubyGem for implementing OAuth 2.0 clients (not servers) in Ruby appli
30
59
 
31
60
  ### Quick Examples
32
61
 
33
- <details>
62
+ <details markdown="1">
34
63
  <summary>Convert the following `curl` command into a token request using this gem...</summary>
35
64
 
36
65
  ```shell
@@ -61,10 +90,11 @@ NOTE: `header` - The content type specified in the `curl` is already the default
61
90
 
62
91
  </details>
63
92
 
64
- <details>
65
- <summary>Complete E2E single file script against [navikt/mock-oauth2-server](https://github.com/navikt/mock-oauth2-server)</summary>
93
+ <details markdown="1">
94
+ <summary>Complete E2E single file script against mock-oauth2-server</summary>
66
95
 
67
- - E2E example using the mock test server added in v2.0.11
96
+ - E2E example uses [navikt/mock-oauth2-server](https://github.com/navikt/mock-oauth2-server), which was added in v2.0.11
97
+ - E2E example does not ship with the released gem, so clone the source to play with it.
68
98
 
69
99
  ```console
70
100
  docker compose -f docker-compose-ssl.yml up -d --wait
@@ -93,26 +123,27 @@ docker compose -f docker-compose-ssl.yml down
93
123
  Troubleshooting: validate connectivity to the mock server
94
124
 
95
125
  - Check container status and port mapping:
96
- - docker compose -f docker-compose-ssl.yml ps
126
+ - `docker compose -f docker-compose-ssl.yml ps`
97
127
  - 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
128
+ - `curl -v http://localhost:8080/default/.well-known/openid-configuration`
129
+ - If that fails immediately, also try: `curl -v --connect-timeout 2 http://127.0.0.1:8080/default/.well-known/openid-configuration`
130
+ - From inside the container (to distinguish container vs. host networking):
131
+ - `docker exec -it oauth2-mock-oauth2-server-1 curl -v http://127.0.0.1:8080/default/.well-known/openid-configuration`
102
132
  - Simple TCP probe from the host:
103
- - nc -vz localhost 8080 # or: ruby -rsocket -e 'TCPSocket.new("localhost",8080).close; puts "tcp ok"'
133
+ - `nc -vz localhost 8080 # or: ruby -rsocket -e 'TCPSocket.new("localhost",8080).close; puts "tcp ok"'`
104
134
  - 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
135
+ - `docker inspect -f '{{ (index (index .NetworkSettings.Ports "8080/tcp") 0).HostPort }}' oauth2-mock-oauth2-server-1`
106
136
  - Look at server logs for readiness/errors:
107
- - docker logs -n 200 oauth2-mock-oauth2-server-1
137
+ - `docker logs -n 200 oauth2-mock-oauth2-server-1`
108
138
  - On Linux, ensure nothing else is bound to 8080 and that firewall/SELinux aren’t blocking:
109
- - ss -ltnp | grep :8080
139
+ - `ss -ltnp | grep :8080`
110
140
 
111
141
  Notes
112
- - Discovery URL pattern is: http://localhost:8080/<realm>/.well-known/openid-configuration, where <realm> defaults to "default".
142
+
143
+ - Discovery URL pattern is: `http://localhost:8080/<realm>/.well-known/openid-configuration`, where `<realm>` defaults to `default`.
113
144
  - You can change these with env vars when running the example:
114
- - E2E_ISSUER_BASE (default: http://localhost:8080)
115
- - E2E_REALM (default: default)
145
+ - `E2E_ISSUER_BASE` (default: http://localhost:8080)
146
+ - `E2E_REALM` (default: default)
116
147
 
117
148
  </details>
118
149
 
@@ -128,107 +159,39 @@ If it seems like you are in the wrong place, you might try one of these:
128
159
 
129
160
  ## 💡 Info you can shake a stick at
130
161
 
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] [![Discussion][⛳gg-discussions-img]][⛳gg-discussions] [![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 | [![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] |
162
+ | Tokens to Remember | [![Gem name][⛳️name-img]][⛳️gem-name] [![Gem namespace][⛳️namespace-img]][⛳️gem-namespace] |
163
+ |-------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
164
+ | 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] |
165
+ | Works with Truffle Ruby | ![Truffle Ruby 22.3 Compat][💎truby-22.3i] ![Truffle Ruby 23.0 Compat][💎truby-23.0i] ![Truffle Ruby 23.1 Compat][💎truby-23.1i] <br/> [![Truffle Ruby 24.1 Compat][💎truby-c-i]][🚎11-c-wf] |
166
+ | 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] |
167
+ | 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] |
168
+ | 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] |
169
+ | 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] |
170
+ | Documentation | [![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] [![GitLab Wiki][📜gl-wiki-img]][📜gl-wiki] [![GitHub Wiki][📜gh-wiki-img]][📜gh-wiki] |
171
+ | 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] |
172
+ | 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] |
173
+ | 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] |
174
+ | `...` 💖 | [![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] |
144
175
 
145
176
  ### Compatibility
146
177
 
147
- * Operating Systems: Linux, MacOS, Windows
148
- * MRI Ruby @ v2.3, v2.4, v2.5, v2.6, v2.7, v3.0, v3.1, v3.2, v3.3, v3.4, 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.
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.
154
- * gem `faraday` @ v0, v1, v2, HEAD ⏩️ [lostisland/faraday](https://github.com/lostisland/faraday)
155
- * gem `jwt` @ v1, v2, v3, HEAD ⏩️ [jwt/ruby-jwt](https://github.com/jwt/ruby-jwt)
156
- * gem `logger` @ v1.2, v1.5, v1.7, HEAD ⏩️ [ruby/logger](https://github.com/ruby/logger)
157
- * gem `multi_xml` @ v0.5, v0.6, v0.7, HEAD ⏩️ [sferik/multi_xml](https://github.com/sferik/multi_xml)
158
- * gem `rack` @ v1.2, v1.6, v2, v3, HEAD ⏩️ [rack/rack](https://github.com/rack/rack)
159
- * gem `snaky_hash` @ v2, HEAD ⏩️ [ruby-oauth/snaky_hash](https://gitlab.com/ruby-oauth/snaky_hash)
160
- * gem `version_gem` @ v1, HEAD ⏩️ [ruby-oauth/version_gem](https://gitlab.com/ruby-oauth/version_gem)
161
-
162
- The last two were extracted from this gem. They are part of the `ruby-oauth` org,
163
- and are developed in tight collaboration with this gem.
164
-
165
- Also, where reasonable, tested against the runtime dependencies of those dependencies:
166
-
167
- * gem `hashie` @ v0, v1, v2, v3, v4, v5, HEAD ⏩️ [hashie/hashie](https://github.com/hashie/hashie)
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
-
172
- #### Upgrading Runtime Gem Dependencies
173
-
174
- This project sits underneath a large portion of the authorization systems on the internet.
175
- According to GitHub's project tracking, which I believe only reports on public projects,
176
- [100,000+ projects](https://github.com/ruby-oauth/oauth2/network/dependents), and
177
- [500+ packages](https://github.com/ruby-oauth/oauth2/network/dependents?dependent_type=PACKAGE) depend on this project.
178
-
179
- That means it is painful for the Ruby community when this gem forces updates to its runtime dependencies.
180
-
181
- As a result, great care, and a lot of time, have been invested to ensure this gem is working with all the
182
- leading versions per each minor version of Ruby of all the runtime dependencies it can install with.
183
-
184
- What does that mean specifically for the runtime dependencies?
185
-
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.
178
+ Compatible with MRI Ruby 2.2.0+, and concordant releases of JRuby, and TruffleRuby.
188
179
 
189
180
  | 🚚 _Amazing_ test matrix was brought to you by | 🔎 appraisal2 🔎 and the color 💚 green 💚 |
190
181
  |------------------------------------------------|--------------------------------------------------------|
191
182
  | 👟 Check it out! | ✨ [github.com/appraisal-rb/appraisal2][💎appraisal2] ✨ |
192
183
 
193
- #### You should upgrade this gem with confidence\*.
194
-
195
- - This gem follows a _strict & correct_ (according to the maintainer of SemVer; [more info][sv-pub-api]) interpretation of SemVer.
196
- - Dropping support for **any** of the runtime dependency versions above will be a major version bump.
197
- - If you aren't on one of the minor versions above, make getting there a priority.
198
- - You should upgrade the dependencies of this gem with confidence\*.
199
- - Please do upgrade, and then, when it goes smooth as butter [please sponsor me][🖇sponsor]. Thanks!
200
-
201
- [sv-pub-api]: #-versioning
202
-
203
- \* MIT license; The only guarantees I make are for [enterprise support](#enterprise-support).
204
-
205
- <details>
206
- <summary>Standard Library Dependencies</summary>
207
-
208
- The various versions of each are tested via the Ruby test matrix, along with whatever Ruby includes them.
209
-
210
- * base64
211
- * cgi
212
- * json
213
- * time
214
- * logger (removed from stdlib in Ruby 3.5 so added as runtime dependency in v2.0.10)
215
-
216
- If you use a gem version of a core Ruby library it should work fine!
217
-
218
- </details>
219
-
220
184
  ### Federated DVCS
221
185
 
222
- <details>
223
- <summary>Find this repo on other forges</summary>
186
+ <details markdown="1">
187
+ <summary>Find this repo on federated forges (Coming soon!)</summary>
224
188
 
225
- | Federated [DVCS][💎d-in-dvcs] Repository | Status | Issues | PRs | Wiki | CI | Discussions |
226
- |-----------------------------------------------|-----------------------------------------------------------------------|---------------------------|--------------------------|---------------------------|--------------------------|------------------------------|
227
- | 🧪 [ruby-oauth/oauth2 on GitLab][📜src-gl] | The Truth | [💚][🤝gl-issues] | [💚][🤝gl-pulls] | [💚][📜wiki] | 🏀 Tiny Matrix | ➖ |
228
- | 🧊 [ruby-oauth/oauth2 on CodeBerg][📜src-cb] | An Ethical Mirror ([Donate][🤝cb-donate]) | [💚][🤝cb-issues] | [💚][🤝cb-pulls] | ➖ | ⭕️ No Matrix | ➖ |
229
- | 🐙 [ruby-oauth/oauth2 on GitHub][📜src-gh] | Another Mirror | [💚][🤝gh-issues] | [💚][🤝gh-pulls] | | 💯 Full Matrix | [💚][gh-discussions] |
230
- | 🤼 [OAuth Ruby Google Group][⛳gg-discussions] | "Active" | | | | | [💚][⛳gg-discussions] |
231
- | 🎮️ [Discord Server][✉️discord-invite] | [![Live Chat on Discord][✉️discord-invite-img-ftb]][✉️discord-invite] | [Let's][✉️discord-invite] | [talk][✉️discord-invite] | [about][✉️discord-invite] | [this][✉️discord-invite] | [library!][✉️discord-invite] |
189
+ | Federated [DVCS][💎d-in-dvcs] Repository | Status | Issues | PRs | Wiki | CI | Discussions |
190
+ |-------------------------------------------------|-----------------------------------------------------------------------|---------------------------|--------------------------|---------------------------|--------------------------|------------------------------|
191
+ | 🧪 [ruby-oauth/oauth2 on GitLab][📜src-gl] | The Truth | [💚][🤝gl-issues] | [💚][🤝gl-pulls] | [💚][📜gl-wiki] | 🐭 Tiny Matrix | ➖ |
192
+ | 🧊 [ruby-oauth/oauth2 on CodeBerg][📜src-cb] | An Ethical Mirror ([Donate][🤝cb-donate]) | [💚][🤝cb-issues] | [💚][🤝cb-pulls] | ➖ | ⭕️ No Matrix | ➖ |
193
+ | 🐙 [ruby-oauth/oauth2 on GitHub][📜src-gh] | Another Mirror | [💚][🤝gh-issues] | [💚][🤝gh-pulls] | [💚][📜gh-wiki] | 💯 Full Matrix | [💚][gh-discussions] |
194
+ | 🎮️ [Discord Server][✉️discord-invite] | [![Live Chat on Discord][✉️discord-invite-img-ftb]][✉️discord-invite] | [Let's][✉️discord-invite] | [talk][✉️discord-invite] | [about][✉️discord-invite] | [this][✉️discord-invite] | [library!][✉️discord-invite] |
232
195
 
233
196
  </details>
234
197
 
@@ -238,7 +201,7 @@ If you use a gem version of a core Ruby library it should work fine!
238
201
 
239
202
  Available as part of the Tidelift Subscription.
240
203
 
241
- <details>
204
+ <details markdown="1">
242
205
  <summary>Need enterprise-level guarantees?</summary>
243
206
 
244
207
  The maintainers of this 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.
@@ -257,143 +220,6 @@ Alternatively:
257
220
 
258
221
  </details>
259
222
 
260
- ## 🚀 Release Documentation
261
-
262
- ### Version 2.0.x
263
-
264
- <details>
265
- <summary>2.0.x CHANGELOG and README</summary>
266
-
267
- | Version | Release Date | CHANGELOG | README |
268
- |---------|--------------|---------------------------------------|---------------------------------|
269
- | 2.0.17 | 2025-09-15 | [v2.0.17 CHANGELOG][2.0.17-changelog] | [v2.0.17 README][2.0.17-readme] |
270
- | 2.0.16 | 2025-09-14 | [v2.0.16 CHANGELOG][2.0.16-changelog] | [v2.0.16 README][2.0.16-readme] |
271
- | 2.0.15 | 2025-09-08 | [v2.0.15 CHANGELOG][2.0.15-changelog] | [v2.0.15 README][2.0.15-readme] |
272
- | 2.0.14 | 2025-08-31 | [v2.0.14 CHANGELOG][2.0.14-changelog] | [v2.0.14 README][2.0.14-readme] |
273
- | 2.0.13 | 2025-08-30 | [v2.0.13 CHANGELOG][2.0.13-changelog] | [v2.0.13 README][2.0.13-readme] |
274
- | 2.0.12 | 2025-05-31 | [v2.0.12 CHANGELOG][2.0.12-changelog] | [v2.0.12 README][2.0.12-readme] |
275
- | 2.0.11 | 2025-05-23 | [v2.0.11 CHANGELOG][2.0.11-changelog] | [v2.0.11 README][2.0.11-readme] |
276
- | 2.0.10 | 2025-05-17 | [v2.0.10 CHANGELOG][2.0.10-changelog] | [v2.0.10 README][2.0.10-readme] |
277
- | 2.0.9 | 2022-09-16 | [v2.0.9 CHANGELOG][2.0.9-changelog] | [v2.0.9 README][2.0.9-readme] |
278
- | 2.0.8 | 2022-09-01 | [v2.0.8 CHANGELOG][2.0.8-changelog] | [v2.0.8 README][2.0.8-readme] |
279
- | 2.0.7 | 2022-08-22 | [v2.0.7 CHANGELOG][2.0.7-changelog] | [v2.0.7 README][2.0.7-readme] |
280
- | 2.0.6 | 2022-07-13 | [v2.0.6 CHANGELOG][2.0.6-changelog] | [v2.0.6 README][2.0.6-readme] |
281
- | 2.0.5 | 2022-07-07 | [v2.0.5 CHANGELOG][2.0.5-changelog] | [v2.0.5 README][2.0.5-readme] |
282
- | 2.0.4 | 2022-07-01 | [v2.0.4 CHANGELOG][2.0.4-changelog] | [v2.0.4 README][2.0.4-readme] |
283
- | 2.0.3 | 2022-06-28 | [v2.0.3 CHANGELOG][2.0.3-changelog] | [v2.0.3 README][2.0.3-readme] |
284
- | 2.0.2 | 2022-06-24 | [v2.0.2 CHANGELOG][2.0.2-changelog] | [v2.0.2 README][2.0.2-readme] |
285
- | 2.0.1 | 2022-06-22 | [v2.0.1 CHANGELOG][2.0.1-changelog] | [v2.0.1 README][2.0.1-readme] |
286
- | 2.0.0 | 2022-06-21 | [v2.0.0 CHANGELOG][2.0.0-changelog] | [v2.0.0 README][2.0.0-readme] |
287
-
288
- </details>
289
-
290
- [2.0.17-changelog]: https://gitlab.com/ruby-oauth/oauth2/-/blob/main/CHANGELOG.md?ref_type=heads#2017---2025-09-15
291
- [2.0.16-changelog]: https://gitlab.com/ruby-oauth/oauth2/-/blob/main/CHANGELOG.md?ref_type=heads#2016---2025-09-14
292
- [2.0.15-changelog]: https://gitlab.com/ruby-oauth/oauth2/-/blob/main/CHANGELOG.md?ref_type=heads#2015---2025-09-08
293
- [2.0.14-changelog]: https://gitlab.com/ruby-oauth/oauth2/-/blob/main/CHANGELOG.md?ref_type=heads#2014---2025-08-31
294
- [2.0.13-changelog]: https://gitlab.com/ruby-oauth/oauth2/-/blob/main/CHANGELOG.md?ref_type=heads#2013---2025-08-30
295
- [2.0.12-changelog]: https://gitlab.com/ruby-oauth/oauth2/-/blob/main/CHANGELOG.md?ref_type=heads#2012---2025-05-31
296
- [2.0.11-changelog]: https://gitlab.com/ruby-oauth/oauth2/-/blob/main/CHANGELOG.md?ref_type=heads#2011---2025-05-23
297
- [2.0.10-changelog]: https://gitlab.com/ruby-oauth/oauth2/-/blob/main/CHANGELOG.md?ref_type=heads#2010---2025-05-17
298
- [2.0.9-changelog]: https://gitlab.com/ruby-oauth/oauth2/-/blob/main/CHANGELOG.md?ref_type=heads#209---2022-09-16
299
- [2.0.8-changelog]: https://gitlab.com/ruby-oauth/oauth2/-/blob/main/CHANGELOG.md?ref_type=heads#208---2022-09-01
300
- [2.0.7-changelog]: https://gitlab.com/ruby-oauth/oauth2/-/blob/main/CHANGELOG.md?ref_type=heads#207---2022-08-22
301
- [2.0.6-changelog]: https://gitlab.com/ruby-oauth/oauth2/-/blob/main/CHANGELOG.md?ref_type=heads#206---2022-07-13
302
- [2.0.5-changelog]: https://gitlab.com/ruby-oauth/oauth2/-/blob/main/CHANGELOG.md?ref_type=heads#205---2022-07-07
303
- [2.0.4-changelog]: https://gitlab.com/ruby-oauth/oauth2/-/blob/main/CHANGELOG.md?ref_type=heads#204---2022-07-01
304
- [2.0.3-changelog]: https://gitlab.com/ruby-oauth/oauth2/-/blob/main/CHANGELOG.md?ref_type=heads#203---2022-06-28
305
- [2.0.2-changelog]: https://gitlab.com/ruby-oauth/oauth2/-/blob/main/CHANGELOG.md?ref_type=heads#202---2022-06-24
306
- [2.0.1-changelog]: https://gitlab.com/ruby-oauth/oauth2/-/blob/main/CHANGELOG.md?ref_type=heads#201---2022-06-22
307
- [2.0.0-changelog]: https://gitlab.com/ruby-oauth/oauth2/-/blob/main/CHANGELOG.md?ref_type=heads#200---2022-06-21
308
-
309
- [2.0.17-readme]: https://gitlab.com/ruby-oauth/oauth2/-/blob/v2.0.17/README.md
310
- [2.0.16-readme]: https://gitlab.com/ruby-oauth/oauth2/-/blob/v2.0.16/README.md
311
- [2.0.15-readme]: https://gitlab.com/ruby-oauth/oauth2/-/blob/v2.0.15/README.md
312
- [2.0.14-readme]: https://gitlab.com/ruby-oauth/oauth2/-/blob/v2.0.14/README.md
313
- [2.0.13-readme]: https://gitlab.com/ruby-oauth/oauth2/-/blob/v2.0.13/README.md
314
- [2.0.12-readme]: https://gitlab.com/ruby-oauth/oauth2/-/blob/v2.0.12/README.md
315
- [2.0.11-readme]: https://gitlab.com/ruby-oauth/oauth2/-/blob/v2.0.11/README.md
316
- [2.0.10-readme]: https://gitlab.com/ruby-oauth/oauth2/-/blob/v2.0.10/README.md
317
- [2.0.9-readme]: https://gitlab.com/ruby-oauth/oauth2/-/blob/v2.0.9/README.md
318
- [2.0.8-readme]: https://gitlab.com/ruby-oauth/oauth2/-/blob/v2.0.8/README.md
319
- [2.0.7-readme]: https://gitlab.com/ruby-oauth/oauth2/-/blob/v2.0.7/README.md
320
- [2.0.6-readme]: https://gitlab.com/ruby-oauth/oauth2/-/blob/v2.0.6/README.md
321
- [2.0.5-readme]: https://gitlab.com/ruby-oauth/oauth2/-/blob/v2.0.5/README.md
322
- [2.0.4-readme]: https://gitlab.com/ruby-oauth/oauth2/-/blob/v2.0.4/README.md
323
- [2.0.3-readme]: https://gitlab.com/ruby-oauth/oauth2/-/blob/v2.0.3/README.md
324
- [2.0.2-readme]: https://gitlab.com/ruby-oauth/oauth2/-/blob/v2.0.2/README.md
325
- [2.0.1-readme]: https://gitlab.com/ruby-oauth/oauth2/-/blob/v2.0.1/README.md
326
- [2.0.0-readme]: https://gitlab.com/ruby-oauth/oauth2/-/blob/v2.0.0/README.md
327
-
328
- ### Older Releases
329
-
330
- <details>
331
- <summary>1.4.x CHANGELOGs and READMEs</summary>
332
-
333
- | Version | Release Date | CHANGELOG | README |
334
- |---------|--------------|---------------------------------------|---------------------------------|
335
- | 1.4.11 | Sep 16, 2022 | [v1.4.11 CHANGELOG][1.4.11-changelog] | [v1.4.11 README][1.4.11-readme] |
336
- | 1.4.10 | Jul 1, 2022 | [v1.4.10 CHANGELOG][1.4.10-changelog] | [v1.4.10 README][1.4.10-readme] |
337
- | 1.4.9 | Feb 20, 2022 | [v1.4.9 CHANGELOG][1.4.9-changelog] | [v1.4.9 README][1.4.9-readme] |
338
- | 1.4.8 | Feb 18, 2022 | [v1.4.8 CHANGELOG][1.4.8-changelog] | [v1.4.8 README][1.4.8-readme] |
339
- | 1.4.7 | Mar 19, 2021 | [v1.4.7 CHANGELOG][1.4.7-changelog] | [v1.4.7 README][1.4.7-readme] |
340
- | 1.4.6 | Mar 19, 2021 | [v1.4.6 CHANGELOG][1.4.6-changelog] | [v1.4.6 README][1.4.6-readme] |
341
- | 1.4.5 | Mar 18, 2021 | [v1.4.5 CHANGELOG][1.4.5-changelog] | [v1.4.5 README][1.4.5-readme] |
342
- | 1.4.4 | Feb 12, 2020 | [v1.4.4 CHANGELOG][1.4.4-changelog] | [v1.4.4 README][1.4.4-readme] |
343
- | 1.4.3 | Jan 29, 2020 | [v1.4.3 CHANGELOG][1.4.3-changelog] | [v1.4.3 README][1.4.3-readme] |
344
- | 1.4.2 | Oct 1, 2019 | [v1.4.2 CHANGELOG][1.4.2-changelog] | [v1.4.2 README][1.4.2-readme] |
345
- | 1.4.1 | Oct 13, 2018 | [v1.4.1 CHANGELOG][1.4.1-changelog] | [v1.4.1 README][1.4.1-readme] |
346
- | 1.4.0 | Jun 9, 2017 | [v1.4.0 CHANGELOG][1.4.0-changelog] | [v1.4.0 README][1.4.0-readme] |
347
- </details>
348
-
349
- [1.4.11-changelog]: https://gitlab.com/ruby-oauth/oauth2/-/blob/main/CHANGELOG.md?ref_type=heads#1411---2022-09-16
350
- [1.4.10-changelog]: https://gitlab.com/ruby-oauth/oauth2/-/blob/main/CHANGELOG.md?ref_type=heads#1410---2022-07-01
351
- [1.4.9-changelog]: https://gitlab.com/ruby-oauth/oauth2/-/blob/main/CHANGELOG.md?ref_type=heads#149---2022-02-20
352
- [1.4.8-changelog]: https://gitlab.com/ruby-oauth/oauth2/-/blob/main/CHANGELOG.md?ref_type=heads#148---2022-02-18
353
- [1.4.7-changelog]: https://gitlab.com/ruby-oauth/oauth2/-/blob/main/CHANGELOG.md?ref_type=heads#147---2021-03-19
354
- [1.4.6-changelog]: https://gitlab.com/ruby-oauth/oauth2/-/blob/main/CHANGELOG.md?ref_type=heads#146---2021-03-19
355
- [1.4.5-changelog]: https://gitlab.com/ruby-oauth/oauth2/-/blob/main/CHANGELOG.md?ref_type=heads#145---2021-03-18
356
- [1.4.4-changelog]: https://gitlab.com/ruby-oauth/oauth2/-/blob/main/CHANGELOG.md?ref_type=heads#144---2020-02-12
357
- [1.4.3-changelog]: https://gitlab.com/ruby-oauth/oauth2/-/blob/main/CHANGELOG.md?ref_type=heads#143---2020-01-29
358
- [1.4.2-changelog]: https://gitlab.com/ruby-oauth/oauth2/-/blob/main/CHANGELOG.md?ref_type=heads#142---2019-10-01
359
- [1.4.1-changelog]: https://gitlab.com/ruby-oauth/oauth2/-/blob/main/CHANGELOG.md?ref_type=heads#141---2018-10-13
360
- [1.4.0-changelog]: https://gitlab.com/ruby-oauth/oauth2/-/blob/main/CHANGELOG.md?ref_type=heads#140---2017-06-09
361
-
362
- [1.4.11-readme]: https://gitlab.com/ruby-oauth/oauth2/-/blob/v1.4.11/README.md
363
- [1.4.10-readme]: https://gitlab.com/ruby-oauth/oauth2/-/blob/v1.4.10/README.md
364
- [1.4.9-readme]: https://gitlab.com/ruby-oauth/oauth2/-/blob/v1.4.9/README.md
365
- [1.4.8-readme]: https://gitlab.com/ruby-oauth/oauth2/-/blob/v1.4.8/README.md
366
- [1.4.7-readme]: https://gitlab.com/ruby-oauth/oauth2/-/blob/v1.4.7/README.md
367
- [1.4.6-readme]: https://gitlab.com/ruby-oauth/oauth2/-/blob/v1.4.6/README.md
368
- [1.4.5-readme]: https://gitlab.com/ruby-oauth/oauth2/-/blob/v1.4.5/README.md
369
- [1.4.4-readme]: https://gitlab.com/ruby-oauth/oauth2/-/blob/v1.4.4/README.md
370
- [1.4.3-readme]: https://gitlab.com/ruby-oauth/oauth2/-/blob/v1.4.3/README.md
371
- [1.4.2-readme]: https://gitlab.com/ruby-oauth/oauth2/-/blob/v1.4.2/README.md
372
- [1.4.1-readme]: https://gitlab.com/ruby-oauth/oauth2/-/blob/v1.4.1/README.md
373
- [1.4.0-readme]: https://gitlab.com/ruby-oauth/oauth2/-/blob/v1.4.0/README.md
374
-
375
- <details>
376
- <summary>1.3.x Readmes</summary>
377
-
378
- | Version | Release Date | Readme |
379
- |---------|--------------|--------------------------------------------------------------|
380
- | 1.3.1 | Mar 3, 2017 | https://gitlab.com/ruby-oauth/oauth2/-/blob/v1.3.1/README.md |
381
- | 1.3.0 | Dec 27, 2016 | https://gitlab.com/ruby-oauth/oauth2/-/blob/v1.3.0/README.md |
382
-
383
- </details>
384
-
385
- <details>
386
- <summary>&le;= 1.2.x Readmes (2016 and before)</summary>
387
-
388
- | Version | Release Date | Readme |
389
- |---------|--------------|--------------------------------------------------------------|
390
- | 1.2.0 | Jun 30, 2016 | https://gitlab.com/ruby-oauth/oauth2/-/blob/v1.2.0/README.md |
391
- | 1.1.0 | Jan 30, 2016 | https://gitlab.com/ruby-oauth/oauth2/-/blob/v1.1.0/README.md |
392
- | 1.0.0 | May 23, 2014 | https://gitlab.com/ruby-oauth/oauth2/-/blob/v1.0.0/README.md |
393
- | < 1.0.0 | Find here | https://gitlab.com/ruby-oauth/oauth2/-/tags |
394
-
395
- </details>
396
-
397
223
  ## ✨ Installation
398
224
 
399
225
  Install the gem and add to the application's Gemfile by executing:
@@ -410,7 +236,7 @@ gem install oauth2
410
236
 
411
237
  ### 🔒 Secure Installation
412
238
 
413
- <details>
239
+ <details markdown="1">
414
240
  <summary>For Medium or High Security Installations</summary>
415
241
 
416
242
  This gem is cryptographically signed, and has verifiable [SHA-256 and SHA-512][💎SHA_checksums] checksums by
@@ -439,6 +265,8 @@ If you want to up your security game full-time:
439
265
  bundle config set --global trust-policy MediumSecurity
440
266
  ```
441
267
 
268
+ `MediumSecurity` instead of `HighSecurity` is necessary if not all the gems you use are signed.
269
+
442
270
  NOTE: Be prepared to track down certs for signed gems and add them the same way you added mine.
443
271
 
444
272
  </details>
@@ -476,7 +304,7 @@ Compatibility is further distinguished as "Best Effort Support" or "Incidental S
476
304
  This gem will install on Ruby versions >= v2.2 for 2.x releases.
477
305
  See `1-4-stable` branch for older rubies.
478
306
 
479
- <details>
307
+ <details markdown="1">
480
308
  <summary>Ruby Engine Compatibility Policy</summary>
481
309
 
482
310
  This gem is tested against MRI, JRuby, and Truffleruby.
@@ -484,15 +312,16 @@ Each of those has varying versions that target a specific version of MRI Ruby.
484
312
  This gem should work in the just-listed Ruby engines according to the targeted MRI compatibility in the table below.
485
313
  If you would like to add support for additional engines,
486
314
  see [gemfiles/README.md](gemfiles/README.md), then submit a PR to the correct maintenance branch as according to the table below.
315
+
487
316
  </details>
488
317
 
489
- <details>
318
+ <details markdown="1">
490
319
  <summary>Ruby Version Compatibility Policy</summary>
491
320
 
492
321
  If something doesn't work on one of these interpreters, it's a bug.
493
322
 
494
323
  This library may inadvertently work (or seem to work) on other Ruby
495
- implementations, however support will only be provided for the versions listed
324
+ implementations; however, support will only be provided for the versions listed
496
325
  above.
497
326
 
498
327
  If you would like this library to support another Ruby version, you may
@@ -501,6 +330,7 @@ run and pass on that implementation. When something breaks on your
501
330
  implementation, you will be responsible for providing patches in a timely
502
331
  fashion. If critical issues for a particular implementation exist at the time
503
332
  of a major release, support for that Ruby version may be dropped.
333
+
504
334
  </details>
505
335
 
506
336
  | | Ruby OAuth2 Version | Maintenance Branch | Targeted Support | Best Effort Support | Incidental Support |
@@ -510,7 +340,7 @@ of a major release, support for that Ruby version may be dropped.
510
340
  | 3️⃣ | older | N/A | Best of luck to you! | Please upgrade! | |
511
341
 
512
342
  NOTE: The 1.4 series will only receive critical security updates.
513
- See [SECURITY.md][🔐security].
343
+ See [SECURITY.md][🔐security] and [IRP.md][🔐irp].
514
344
 
515
345
  ## ⚙️ Configuration
516
346
 
@@ -531,13 +361,13 @@ Some OAuth 2.0 standards legitimately have multiple tokens.
531
361
  You may need to subclass `OAuth2::AccessToken`, or write your own custom alternative to it, and pass it in.
532
362
  Specify your custom class with the `access_token_class` option.
533
363
 
534
- If you only need one token you can, as of v2.0.10,
364
+ If you only need one token, you can, as of v2.0.10,
535
365
  specify the exact token name you want to extract via the `OAuth2::AccessToken` using
536
366
  the `token_name` option.
537
367
 
538
368
  You'll likely need to do some source diving.
539
369
  This gem has 100% test coverage for lines and branches, so the specs are a great place to look for ideas.
540
- If you have time and energy please contribute to the documentation!
370
+ If you have time and energy, please contribute to the documentation!
541
371
 
542
372
  ## 🔧 Basic Usage
543
373
 
@@ -558,7 +388,7 @@ response.class.name
558
388
 
559
389
  ### Relative `authorize_url` and `token_url` (Not on site root, Just Works!)
560
390
 
561
- In above example, the default Authorization URL is `oauth/authorize` and default Access Token URL is `oauth/token`, and, as they are missing a leading `/`, both are relative.
391
+ In the above example, the default Authorization URL is `oauth/authorize` and default Access Token URL is `oauth/token`, and, as they are missing a leading `/`, both are relative.
562
392
 
563
393
  ```ruby
564
394
  client = OAuth2::Client.new("client_id", "client_secret", site: "https://example.org/nested/directory/on/your/server")
@@ -637,7 +467,11 @@ These extensions work regardless of whether you used the global or discrete conf
637
467
 
638
468
  There are a few hacks you may need in your class to support Ruby < 2.4.2 or < 2.6.
639
469
  They are likely not needed if you are on a newer Ruby.
640
- See [response_spec.rb](https://github.com/ruby-oauth/oauth2/blob/main/spec/oauth2/response_spec.rb) if you need to study the hacks for older Rubies.
470
+ Expand the examples below, or the [ruby-oauth/snaky_hash](https://gitlab.com/ruby-oauth/snaky_hash) gem,
471
+ or [response_spec.rb](https://github.com/ruby-oauth/oauth2/blob/main/spec/oauth2/response_spec.rb), for more ideas, especially if you need to study the hacks for older Rubies.
472
+
473
+ <details markdown="1">
474
+ <summary>See Examples</summary>
641
475
 
642
476
  ```ruby
643
477
  class MySnakyHash < SnakyHash::StringKeyed
@@ -693,7 +527,7 @@ class MySnakyHash < SnakyHash::StringKeyed
693
527
  end
694
528
  ```
695
529
 
696
- See [response_spec.rb](https://github.com/ruby-oauth/oauth2/blob/main/spec/oauth2/response_spec.rb), or the [ruby-oauth/snaky_hash](https://gitlab.com/ruby-oauth/snaky_hash) gem for more ideas.
530
+ </details>
697
531
 
698
532
  #### Prefer camelCase over snake_case? => snaky: false
699
533
 
@@ -706,7 +540,7 @@ response.parsed["additionalData"] # => "additional"
706
540
  response.parsed.class.name # => Hash (just, regular old Hash)
707
541
  ```
708
542
 
709
- <details>
543
+ <details markdown="1">
710
544
  <summary>Debugging & Logging</summary>
711
545
 
712
546
  Set an environment variable as per usual (e.g. with [dotenv](https://github.com/bkeepers/dotenv)).
@@ -728,6 +562,7 @@ client = OAuth2::Client.new(
728
562
  logger: Logger.new("example.log", "weekly"),
729
563
  )
730
564
  ```
565
+
731
566
  </details>
732
567
 
733
568
  ### OAuth2::Response
@@ -751,16 +586,20 @@ a hash of the values), or `from_kvform` (if you have an
751
586
  `application/x-www-form-urlencoded` encoded string of the values).
752
587
 
753
588
  Options (since v2.0.x unless noted):
754
- - expires_latency (Integer | nil): Seconds to subtract from expires_in when computing #expired? to offset latency.
755
- - 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).
756
- - mode (Symbol | Proc | Hash): Controls how the token is transmitted on requests made via this AccessToken instance.
757
- - :header Send as Authorization: Bearer <token> header (default and preferred by OAuth 2.1 draft guidance).
758
- - :query — Send as access_token query parameter (discouraged in general, but required by some providers).
589
+
590
+ - `expires_latency` (Integer | nil): Seconds to subtract from expires_in when computing #expired? to offset latency.
591
+ - `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).
592
+ - `mode` (Symbol | Proc | Hash): Controls how the token is transmitted on requests made via this AccessToken instance.
593
+ - `:header` — Send as Authorization: Bearer <token> header (default and preferred by OAuth 2.1 draft guidance).
594
+ - `:query` — Send as access_token query parameter (discouraged in general, but required by some providers).
759
595
  - Verb-dependent (since v2.0.15): Provide either:
760
- - a Proc taking |verb| and returning :header or :query, or
761
- - a Hash with verb symbols as keys, for example: {get: :query, post: :header, delete: :header}.
596
+ - a `Proc` taking `|verb|` and returning `:header` or `:query`, or
597
+ - a `Hash` with verb symbols as keys, for example `{get: :query, post: :header, delete: :header}`.
762
598
 
763
- 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.
599
+ Note: Verb-dependent mode supports providers like Instagram that require query mode for `GET` and header mode for `POST`/`DELETE`
600
+
601
+ - Verb-dependent mode via `Proc` was added in v2.0.15
602
+ - Verb-dependent mode via `Hash` was added in v2.0.16
764
603
 
765
604
  ### OAuth2::Error
766
605
 
@@ -777,6 +616,7 @@ Response instance will contain the `OAuth2::Error` instance.
777
616
  ### Authorization Grants
778
617
 
779
618
  Note on OAuth 2.1 (draft):
619
+
780
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.
781
621
  - Redirect URIs must be compared using exact string matching by the Authorization Server.
782
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.
@@ -785,6 +625,7 @@ Note on OAuth 2.1 (draft):
785
625
  - The definitions of public and confidential clients are simplified to refer only to whether the client has credentials.
786
626
 
787
627
  References:
628
+
788
629
  - OAuth 2.1 draft: https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-13
789
630
  - Aaron Parecki: https://aaronparecki.com/2019/12/12/21/its-time-for-oauth-2-dot-1
790
631
  - FusionAuth: https://fusionauth.io/blog/2020/04/15/whats-new-in-oauth-2-1
@@ -801,6 +642,7 @@ use. They are available via the [`#auth_code`](https://gitlab.com/ruby-oauth/oau
801
642
  [`#assertion`](https://gitlab.com/ruby-oauth/oauth2/-/blob/main/lib/oauth2/strategy/assertion.rb) methods respectively.
802
643
 
803
644
  These aren't full examples, but demonstrative of the differences between usage for each strategy.
645
+
804
646
  ```ruby
805
647
  auth_url = client.auth_code.authorize_url(redirect_uri: "http://localhost:8080/oauth/callback")
806
648
  access = client.auth_code.get_token("code_value", redirect_uri: "http://localhost:8080/oauth/callback")
@@ -884,7 +726,7 @@ access = client.password.get_token("jdoe", "s3cret", scope: "read")
884
726
 
885
727
  #### Examples
886
728
 
887
- <details>
729
+ <details markdown="1">
888
730
  <summary>JHipster UAA (Spring Cloud) password grant example (legacy; avoid when possible)</summary>
889
731
 
890
732
  ```ruby
@@ -925,6 +767,7 @@ puts access.to_hash # full token response
925
767
  ```
926
768
 
927
769
  Notes:
770
+
928
771
  - Resource Owner Password Credentials (ROPC) is deprecated in OAuth 2.1 and discouraged. Prefer Authorization Code + PKCE.
929
772
  - If your deployment strictly demands the X-XSRF-TOKEN header, first fetch it from an endpoint that sets the XSRF-TOKEN cookie (often "/" or a login page) and pass it to headers.
930
773
  - For Basic auth, auth_scheme: :basic_auth handles the Authorization header; you do not need to base64-encode manually.
@@ -934,6 +777,7 @@ Notes:
934
777
  ### Instagram API (verb‑dependent token mode)
935
778
 
936
779
  Providers like Instagram require the access token to be sent differently depending on the HTTP verb:
780
+
937
781
  - GET requests: token must be in the query string (?access_token=...)
938
782
  - POST/DELETE requests: token must be in the Authorization header (Bearer ...)
939
783
 
@@ -998,8 +842,9 @@ me = long_lived.get("/me", params: {fields: "id,username"}).parsed
998
842
  ```
999
843
 
1000
844
  Tips:
1001
- - Avoid query‑string bearer tokens unless required by your provider. Instagram explicitly requires it for GET.
1002
- - If you need a custom rule, you can pass a Proc for mode, e.g. mode: ->(verb) { verb == :get ? :query : :header }.
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 }`.
1003
848
 
1004
849
  ### Refresh Tokens
1005
850
 
@@ -1104,16 +949,17 @@ resp = access.get("/v1/protected")
1104
949
  ```
1105
950
 
1106
951
  Notes:
1107
- - Files must contain the appropriate PEMs. The private key may be encrypted; if so, pass a password to OpenSSL::PKey::RSA.new(File.read(path), ENV["KEY_PASSWORD"]).
952
+
953
+ - Files must contain the appropriate PEMs. The private key may be encrypted; if so, pass a password to `OpenSSL::PKey::RSA.new(File.read(path), ENV["KEY_PASSWORD"])`.
1108
954
  - If your certificate and key are in a PKCS#12/PFX bundle, you can load them like:
1109
- - p12 = OpenSSL::PKCS12.new(File.read("client.p12"), ENV["P12_PASSWORD"])
1110
- - client_cert = p12.certificate; client_key = p12.key
955
+ - `p12 = OpenSSL::PKCS12.new(File.read("client.p12"), ENV["P12_PASSWORD"])`
956
+ - `client_cert = p12.certificate; client_key = p12.key`
1111
957
  - Server trust:
1112
- - If your environment does not have system CAs, specify ca_file or ca_path inside the ssl: hash.
1113
- - Keep verify: true in production. Set verify: false only for local testing.
1114
- - Faraday adapter: Any adapter that supports Ruby’s OpenSSL should work. net_http (default) and net_http_persistent are common choices.
958
+ - If your environment does not have system CAs, specify `ca_file` or `ca_path` inside the `ssl:` hash.
959
+ - Keep `verify: true` in production. Set `verify: false` only for local testing.
960
+ - Faraday adapter: Any adapter that supports Ruby’s OpenSSL should work. `net_http` (default) and `net_http_persistent` are common choices.
1115
961
  - Scope of mTLS: The SSL client cert is applied to any HTTPS request made by this client (token and resource requests) to the configured site base URL (and absolute URLs you call with the same client).
1116
- - OIDC tie-in: Some OPs require tls_client_auth at the token endpoint per OIDC/OAuth specifications. That is enabled via auth_scheme: :tls_client_auth as shown above.
962
+ - OIDC tie-in: Some OPs require tls_client_auth at the token endpoint per OIDC/OAuth specifications. That is enabled via `auth_scheme: :tls_client_auth` as shown above.
1117
963
 
1118
964
  #### Authentication schemes for the token request
1119
965
 
@@ -1145,9 +991,9 @@ client = OAuth2::Client.new(
1145
991
  end
1146
992
  ```
1147
993
 
1148
- ##### Using flat query params (Faraday::FlatParamsEncoder)
994
+ ##### Using flat query params (`Faraday::FlatParamsEncoder`)
1149
995
 
1150
- Some APIs expect repeated key parameters to be sent as flat params rather than arrays. Faraday provides FlatParamsEncoder for this purpose. You can configure the oauth2 client to use it when building requests.
996
+ Some APIs expect repeated key parameters to be sent as flat params rather than arrays. Faraday provides `FlatParamsEncoder` for this purpose. You can configure the oauth2 client to use it when building requests.
1151
997
 
1152
998
  ```ruby
1153
999
  require "faraday"
@@ -1277,26 +1123,29 @@ and [Tidelift][🏙️entsup-tidelift].
1277
1123
 
1278
1124
  ### Open Collective for Individuals
1279
1125
 
1126
+ Support us with a monthly donation and help us continue our activities. [[Become a backer](https://opencollective.com/ruby-oauth#backer)]
1127
+
1128
+ NOTE: [kettle-readme-backers][kettle-readme-backers] updates this list every day, automatically.
1129
+
1280
1130
  <!-- OPENCOLLECTIVE-INDIVIDUALS:START -->
1281
1131
  No backers yet. Be the first!
1282
1132
  <!-- OPENCOLLECTIVE-INDIVIDUALS:END -->
1283
1133
 
1284
- Support us with a monthly donation and help us continue our activities. [[Become a backer](https://opencollective.com/ruby-oauth#backer)]
1285
-
1286
1134
  ### Open Collective for Organizations
1287
1135
 
1136
+ Become a sponsor and get your logo on our README on GitHub with a link to your site. [[Become a sponsor](https://opencollective.com/ruby-oauth#sponsor)]
1137
+
1138
+ NOTE: [kettle-readme-backers][kettle-readme-backers] updates this list every day, automatically.
1139
+
1288
1140
  <!-- OPENCOLLECTIVE-ORGANIZATIONS:START -->
1289
1141
  No sponsors yet. Be the first!
1290
1142
  <!-- OPENCOLLECTIVE-ORGANIZATIONS:END -->
1291
1143
 
1292
- Become a sponsor and get your logo on our README on GitHub with a link to your site. [[Become a sponsor](https://opencollective.com/ruby-oauth#sponsor)]
1144
+ [kettle-readme-backers]: https://github.com/ruby-oauth/oauth2/blob/main/exe/kettle-readme-backers
1293
1145
 
1294
1146
  ### Another way to support open-source
1295
1147
 
1296
- > How wonderful it is that nobody need wait a single moment before starting to improve the world.<br/>
1297
- >—Anne Frank
1298
-
1299
- I’m driven by a passion to foster a thriving open-source community – a space where people can tackle complex problems, no matter how small. Revitalizing libraries that have fallen into disrepair, and building new libraries focused on solving real-world challenges, are my passions — totaling 79 hours of FLOSS coding over just the past seven days, a pretty regular week for me. I was recently affected by layoffs, and the tech jobs market is unwelcoming. I’m reaching out here because your support would significantly aid my efforts to provide for my family, and my farm (11 🐔 chickens, 2 🐶 dogs, 3 🐰 rabbits, 8 🐈‍ cats).
1148
+ I’m driven by a passion to foster a thriving open-source community – a space where people can tackle complex problems, no matter how small. Revitalizing libraries that have fallen into disrepair, and building new libraries focused on solving real-world challenges, are my passions. I was recently affected by layoffs, and the tech jobs market is unwelcoming. I’m reaching out here because your support would significantly aid my efforts to provide for my family, and my farm (11 🐔 chickens, 2 🐶 dogs, 3 🐰 rabbits, 8 🐈‍ cats).
1300
1149
 
1301
1150
  If you work at a company that uses my work, please encourage them to support me as a corporate sponsor. My work on gems you use might show up in `bundle fund`.
1302
1151
 
@@ -1304,14 +1153,14 @@ I’m developing a new library, [floss_funding][🖇floss-funding-gem], designed
1304
1153
 
1305
1154
  **[Floss-Funding.dev][🖇floss-funding.dev]: 👉️ No network calls. 👉️ No tracking. 👉️ No oversight. 👉️ Minimal crypto hashing. 💡 Easily disabled nags**
1306
1155
 
1307
- [![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]
1156
+ [![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 efforts at ko-fi.com][🖇kofi-img]][🖇kofi] [![Donate to my FLOSS efforts using Patreon][🖇patreon-img]][🖇patreon]
1308
1157
 
1309
1158
  ## 🔐 Security
1310
1159
 
1311
1160
  To report a security vulnerability, please use the [Tidelift security contact](https://tidelift.com/security).
1312
1161
  Tidelift will coordinate the fix and disclosure.
1313
1162
 
1314
- For more see [SECURITY.md][🔐security].
1163
+ For more see [SECURITY.md][🔐security], [THREAT_MODEL.md][🔐threat-model], and [IRP.md][🔐irp].
1315
1164
 
1316
1165
  ## 🤝 Contributing
1317
1166
 
@@ -1329,11 +1178,11 @@ See [CONTRIBUTING.md][🤝contributing].
1329
1178
 
1330
1179
  ### Code Coverage
1331
1180
 
1332
- [![Coverage Graph][🔑codecov-g]][🔑codecov]
1181
+ [![Coverage Graph][🏀codecov-g]][🏀codecov]
1333
1182
 
1334
- [![Coveralls Test Coverage][🔑coveralls-img]][🔑coveralls]
1183
+ [![Coveralls Test Coverage][🏀coveralls-img]][🏀coveralls]
1335
1184
 
1336
- [![QLTY Test Coverage][🔑qlty-covi]][🔑qlty-cov]
1185
+ [![QLTY Test Coverage][🏀qlty-covi]][🏀qlty-cov]
1337
1186
 
1338
1187
  ### 🪇 Code of Conduct
1339
1188
 
@@ -1383,12 +1232,11 @@ For example:
1383
1232
  spec.add_dependency("oauth2", "~> 2.0")
1384
1233
  ```
1385
1234
 
1386
- <details>
1235
+ <details markdown="1">
1387
1236
  <summary>📌 Is "Platform Support" part of the public API? More details inside.</summary>
1388
1237
 
1389
1238
  SemVer should, IMO, but doesn't explicitly, say that dropping support for specific Platforms
1390
- is a *breaking change* to an API.
1391
- It is obvious to many, but not all, and since the spec is silent, the bike shedding is endless.
1239
+ is a *breaking change* to an API, and for that reason the bike shedding is endless.
1392
1240
 
1393
1241
  To get a better understanding of how SemVer is intended to work over a project's lifetime,
1394
1242
  read this article from the creator of SemVer:
@@ -1409,7 +1257,7 @@ See [LICENSE.txt][📄license] for the official [Copyright Notice][📄copyright
1409
1257
 
1410
1258
  <ul>
1411
1259
  <li>
1412
- Copyright (c) 2017–2025 Peter H. Boling, of
1260
+ Copyright (c) 2017 2025 Peter H. Boling, of
1413
1261
  <a href="https://discord.gg/3qme4XHNKN">
1414
1262
  Galtzo.com
1415
1263
  <picture>
@@ -1418,15 +1266,15 @@ See [LICENSE.txt][📄license] for the official [Copyright Notice][📄copyright
1418
1266
  </a>, and oauth2 contributors.
1419
1267
  </li>
1420
1268
  <li>
1421
- Copyright (c) 2011-2013 Michael Bleigh and Intridea, Inc.
1269
+ Copyright (c) 2011 - 2013 Michael Bleigh and Intridea, Inc.
1422
1270
  </li>
1423
1271
  </ul>
1424
1272
 
1425
1273
  ## 🤑 A request for help
1426
1274
 
1427
1275
  Maintainers have teeth and need to pay their dentists.
1428
- After getting laid off in an RIF in March and filled with many dozens of rejections,
1429
- I'm now spending ~60+ hours a week building open source tools.
1276
+ After getting laid off in an RIF in March, and encountering difficulty finding a new one,
1277
+ I began spending most of my time building open source tools.
1430
1278
  I'm hoping to be able to pay for my kids' health insurance this month,
1431
1279
  so if you value the work I am doing, I need your support.
1432
1280
  Please consider sponsoring me or the project.
@@ -1437,7 +1285,7 @@ To join the community or get help 👇️ Join the Discord.
1437
1285
 
1438
1286
  To say "thanks!" ☝️ Join the Discord or 👇️ send money.
1439
1287
 
1440
- [![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]
1288
+ [![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] 💌 [![Donate on PayPal][🖇paypal-bottom-img]][🖇paypal]
1441
1289
 
1442
1290
  ### Please give the project a star ⭐ ♥.
1443
1291
 
@@ -1485,7 +1333,7 @@ Thanks for RTFM. ☺️
1485
1333
  [✇bundle-group-pattern]: https://gist.github.com/pboling/4564780
1486
1334
  [⛳️gem-namespace]: https://github.com/ruby-oauth/oauth2
1487
1335
  [⛳️namespace-img]: https://img.shields.io/badge/namespace-OAuth2-3C2D2D.svg?style=square&logo=ruby&logoColor=white
1488
- [⛳️gem-name]: https://rubygems.org/gems/oauth2
1336
+ [⛳️gem-name]: https://bestgems.org/gems/oauth2
1489
1337
  [⛳️name-img]: https://img.shields.io/badge/name-oauth2-3C2D2D.svg?style=square&logo=rubygems&logoColor=red
1490
1338
  [⛳️tag-img]: https://img.shields.io/github/tag/ruby-oauth/oauth2.svg
1491
1339
  [⛳️tag]: http://github.com/ruby-oauth/oauth2/releases
@@ -1530,22 +1378,24 @@ Thanks for RTFM. ☺️
1530
1378
  [📜src-gh]: https://github.com/ruby-oauth/oauth2
1531
1379
  [📜docs-cr-rd-img]: https://img.shields.io/badge/RubyDoc-Current_Release-943CD2?style=for-the-badge&logo=readthedocs&logoColor=white
1532
1380
  [📜docs-head-rd-img]: https://img.shields.io/badge/YARD_on_Galtzo.com-HEAD-943CD2?style=for-the-badge&logo=readthedocs&logoColor=white
1533
- [📜wiki]: https://gitlab.com/ruby-oauth/oauth2/-/wikis/home
1534
- [📜wiki-img]: https://img.shields.io/badge/wiki-examples-943CD2.svg?style=for-the-badge&logo=Wiki&logoColor=white
1535
- [👽dl-rank]: https://rubygems.org/gems/oauth2
1381
+ [📜gl-wiki]: https://gitlab.com/ruby-oauth/oauth2/-/wikis/home
1382
+ [📜gh-wiki]: https://github.com/ruby-oauth/oauth2/wiki
1383
+ [📜gl-wiki-img]: https://img.shields.io/badge/wiki-examples-943CD2.svg?style=for-the-badge&logo=gitlab&logoColor=white
1384
+ [📜gh-wiki-img]: https://img.shields.io/badge/wiki-examples-943CD2.svg?style=for-the-badge&logo=github&logoColor=white
1385
+ [👽dl-rank]: https://bestgems.org/gems/oauth2
1536
1386
  [👽dl-ranki]: https://img.shields.io/gem/rd/oauth2.svg
1537
1387
  [👽oss-help]: https://www.codetriage.com/ruby-oauth/oauth2
1538
1388
  [👽oss-helpi]: https://www.codetriage.com/ruby-oauth/oauth2/badges/users.svg
1539
- [👽version]: https://rubygems.org/gems/oauth2
1389
+ [👽version]: https://bestgems.org/gems/oauth2
1540
1390
  [👽versioni]: https://img.shields.io/gem/v/oauth2.svg
1541
- [🔑qlty-mnt]: https://qlty.sh/gh/ruby-oauth/projects/oauth2
1542
- [🔑qlty-mnti]: https://qlty.sh/gh/ruby-oauth/projects/oauth2/maintainability.svg
1543
- [🔑qlty-cov]: https://qlty.sh/gh/ruby-oauth/projects/oauth2/metrics/code?sort=coverageRating
1544
- [🔑qlty-covi]: https://qlty.sh/gh/ruby-oauth/projects/oauth2/coverage.svg
1545
- [🔑codecov]: https://codecov.io/gh/ruby-oauth/oauth2
1546
- [🔑codecovi]: https://codecov.io/gh/ruby-oauth/oauth2/graph/badge.svg
1547
- [🔑coveralls]: https://coveralls.io/github/ruby-oauth/oauth2?branch=main
1548
- [🔑coveralls-img]: https://coveralls.io/repos/github/ruby-oauth/oauth2/badge.svg?branch=main
1391
+ [🏀qlty-mnt]: https://qlty.sh/gh/ruby-oauth/projects/oauth2
1392
+ [🏀qlty-mnti]: https://qlty.sh/gh/ruby-oauth/projects/oauth2/maintainability.svg
1393
+ [🏀qlty-cov]: https://qlty.sh/gh/ruby-oauth/projects/oauth2/metrics/code?sort=coverageRating
1394
+ [🏀qlty-covi]: https://qlty.sh/gh/ruby-oauth/projects/oauth2/coverage.svg
1395
+ [🏀codecov]: https://codecov.io/gh/ruby-oauth/oauth2
1396
+ [🏀codecovi]: https://codecov.io/gh/ruby-oauth/oauth2/graph/badge.svg
1397
+ [🏀coveralls]: https://coveralls.io/github/ruby-oauth/oauth2?branch=main
1398
+ [🏀coveralls-img]: https://coveralls.io/repos/github/ruby-oauth/oauth2/badge.svg?branch=main
1549
1399
  [🖐codeQL]: https://github.com/ruby-oauth/oauth2/security/code-scanning
1550
1400
  [🖐codeQL-img]: https://github.com/ruby-oauth/oauth2/actions/workflows/codeql-analysis.yml/badge.svg
1551
1401
  [🚎1-an-wf]: https://github.com/ruby-oauth/oauth2/actions/workflows/ancient.yml
@@ -1564,8 +1414,6 @@ Thanks for RTFM. ☺️
1564
1414
  [🚎7-us-wfi]: https://github.com/ruby-oauth/oauth2/actions/workflows/unsupported.yml/badge.svg
1565
1415
  [🚎8-ho-wf]: https://github.com/ruby-oauth/oauth2/actions/workflows/hoary.yml
1566
1416
  [🚎8-ho-wfi]: https://github.com/ruby-oauth/oauth2/actions/workflows/hoary.yml/badge.svg
1567
- [🚎9-t-wf]: https://github.com/ruby-oauth/oauth2/actions/workflows/truffle.yml
1568
- [🚎9-t-wfi]: https://github.com/ruby-oauth/oauth2/actions/workflows/truffle.yml/badge.svg
1569
1417
  [🚎10-j-wf]: https://github.com/ruby-oauth/oauth2/actions/workflows/jruby.yml
1570
1418
  [🚎10-j-wfi]: https://github.com/ruby-oauth/oauth2/actions/workflows/jruby.yml/badge.svg
1571
1419
  [🚎11-c-wf]: https://github.com/ruby-oauth/oauth2/actions/workflows/current.yml
@@ -1594,7 +1442,7 @@ Thanks for RTFM. ☺️
1594
1442
  [💎ruby-headi]: https://img.shields.io/badge/Ruby-HEAD-CC342D?style=for-the-badge&logo=ruby&logoColor=blue
1595
1443
  [💎truby-22.3i]: https://img.shields.io/badge/Truffle_Ruby-22.3_(%F0%9F%9A%ABCI)-AABBCC?style=for-the-badge&logo=ruby&logoColor=pink
1596
1444
  [💎truby-23.0i]: https://img.shields.io/badge/Truffle_Ruby-23.0_(%F0%9F%9A%ABCI)-AABBCC?style=for-the-badge&logo=ruby&logoColor=pink
1597
- [💎truby-23.1i]: https://img.shields.io/badge/Truffle_Ruby-23.1-34BCB1?style=for-the-badge&logo=ruby&logoColor=pink
1445
+ [💎truby-23.1i]: https://img.shields.io/badge/Truffle_Ruby-23.1_(%F0%9F%9A%ABCI)-AABBCC?style=for-the-badge&logo=ruby&logoColor=pink
1598
1446
  [💎truby-c-i]: https://img.shields.io/badge/Truffle_Ruby-current-34BCB1?style=for-the-badge&logo=ruby&logoColor=green
1599
1447
  [💎truby-headi]: https://img.shields.io/badge/Truffle_Ruby-HEAD-34BCB1?style=for-the-badge&logo=ruby&logoColor=blue
1600
1448
  [💎jruby-9.1i]: https://img.shields.io/badge/JRuby-9.1_(%F0%9F%9A%ABCI)-AABBCC?style=for-the-badge&logo=ruby&logoColor=red
@@ -1611,7 +1459,7 @@ Thanks for RTFM. ☺️
1611
1459
  [🤝cb-pulls]: https://codeberg.org/ruby-oauth/oauth2/pulls
1612
1460
  [🤝cb-donate]: https://donate.codeberg.org/
1613
1461
  [🤝contributing]: CONTRIBUTING.md
1614
- [🔑codecov-g]: https://codecov.io/gh/ruby-oauth/oauth2/graphs/tree.svg
1462
+ [🏀codecov-g]: https://codecov.io/gh/ruby-oauth/oauth2/graphs/tree.svg
1615
1463
  [🖐contrib-rocks]: https://contrib.rocks
1616
1464
  [🖐contributors]: https://github.com/ruby-oauth/oauth2/graphs/contributors
1617
1465
  [🖐contributors-img]: https://contrib.rocks/image?repo=ruby-oauth/oauth2
@@ -1626,12 +1474,16 @@ Thanks for RTFM. ☺️
1626
1474
  [📌changelog]: CHANGELOG.md
1627
1475
  [📗keep-changelog]: https://keepachangelog.com/en/1.0.0/
1628
1476
  [📗keep-changelog-img]: https://img.shields.io/badge/keep--a--changelog-1.0.0-34495e.svg?style=flat
1629
- [📌gitmoji]:https://gitmoji.dev
1630
- [📌gitmoji-img]:https://img.shields.io/badge/gitmoji_commits-%20%F0%9F%98%9C%20%F0%9F%98%8D-34495e.svg?style=flat-square
1477
+ [📌gitmoji]: https://gitmoji.dev
1478
+ [📌gitmoji-img]: https://img.shields.io/badge/gitmoji_commits-%20%F0%9F%98%9C%20%F0%9F%98%8D-34495e.svg?style=flat-square
1631
1479
  [🧮kloc]: https://www.youtube.com/watch?v=dQw4w9WgXcQ
1632
1480
  [🧮kloc-img]: https://img.shields.io/badge/KLOC-0.526-FFDD67.svg?style=for-the-badge&logo=YouTube&logoColor=blue
1633
1481
  [🔐security]: SECURITY.md
1634
1482
  [🔐security-img]: https://img.shields.io/badge/security-policy-259D6C.svg?style=flat
1483
+ [🔐irp]: IRP.md
1484
+ [🔐irp-img]: https://img.shields.io/badge/IRP-259D6C.svg?style=flat
1485
+ [🔐threat-model]: THREAT_MODEL.md
1486
+ [🔐threat-model-img]: https://img.shields.io/badge/threat-model-259D6C.svg?style=flat
1635
1487
  [📄copyright-notice-explainer]: https://opensource.stackexchange.com/questions/5778/why-do-licenses-such-as-the-mit-license-specify-a-single-year
1636
1488
  [📄license]: LICENSE.txt
1637
1489
  [📄license-ref]: https://opensource.org/licenses/MIT
@@ -1659,12 +1511,3 @@ Thanks for RTFM. ☺️
1659
1511
  <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>
1660
1512
 
1661
1513
  </details>
1662
-
1663
-
1664
- <details>
1665
- <summary>Broken badges</summary>
1666
-
1667
- [![Coverage Graph][🔑codecov-g]][🔑codecov]
1668
- [![CodeCov Test Coverage][🔑codecovi]][🔑codecov]
1669
-
1670
- </details>