From 11b8909634e78d7b90763fd62b6084dde131cfd5 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Tue, 1 Oct 2019 03:12:41 -0600
Subject: [PATCH 001/163] Default to latest Ruby

---
 .gitignore    | 2 +-
 .ruby-version | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/.gitignore b/.gitignore
index 36762cf9..6480a03a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -16,4 +16,4 @@ rdoc/*
 /gemfiles/*.gemfile.lock
 
 # CI bundle
-/gemfiles/vendor/
\ No newline at end of file
+/gemfiles/vendor/
diff --git a/.ruby-version b/.ruby-version
index 68b3a4cd..ec1cf33c 100644
--- a/.ruby-version
+++ b/.ruby-version
@@ -1 +1 @@
-1.9.3-p551
+2.6.3

From 369d6514f73ba9a752156d6a66b01c233dee1472 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Tue, 1 Oct 2019 03:37:55 -0600
Subject: [PATCH 002/163] Cleanup CI

---
 .travis.yml                  | 6 ++++--
 gemfiles/truffleruby.gemfile | 3 +++
 2 files changed, 7 insertions(+), 2 deletions(-)
 create mode 100644 gemfiles/truffleruby.gemfile

diff --git a/.travis.yml b/.travis.yml
index 79b25172..9538619d 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -30,8 +30,7 @@ matrix:
     - rvm: jruby-head
     - rvm: ruby-head
     - rvm: truffleruby
-    - rvm: jruby-9.0 # targets MRI v2.0
-      gemfile: gemfiles/jruby_9.0.gemfile
+    - rvm: jruby-9.0
   fast_finish: true
   include:
 #    - rvm: jruby-1.7 # targets MRI v1.9
@@ -40,6 +39,8 @@ matrix:
       gemfile: gemfiles/ruby_1.9.gemfile
     - rvm: 2.0
       gemfile: gemfiles/ruby_2.0.gemfile
+    - rvm: jruby-9.0 # targets MRI v2.0
+      gemfile: gemfiles/jruby_9.0.gemfile
     - rvm: 2.1
       gemfile: gemfiles/ruby_2.1.gemfile
     # DEPRECATION WARNING
@@ -64,5 +65,6 @@ matrix:
     - rvm: ruby-head
       gemfile: gemfiles/ruby_head.gemfile
     - rvm: truffleruby
+      gemfile: gemfiles/truffleruby.gemfile
 
 sudo: false
diff --git a/gemfiles/truffleruby.gemfile b/gemfiles/truffleruby.gemfile
new file mode 100644
index 00000000..a02c547f
--- /dev/null
+++ b/gemfiles/truffleruby.gemfile
@@ -0,0 +1,3 @@
+source 'https://rubygems.org'
+
+gemspec :path => '../'

From 06f5a0810ad5c6f6686a88cce0af755f29e9b0eb Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Tue, 1 Oct 2019 03:40:00 -0600
Subject: [PATCH 003/163] Prepare for 1.4.2 release

---
 CHANGELOG.md | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index fa957410..58796f91 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,10 @@ All notable changes to this project will be documented in this file.
 
 - no changes yet
 
+## [1.4.2] - 2019-10-01
+
+- [#478](https://github.com/oauth-xx/oauth2/pull/478) - support latest version of faraday & fix build (@pboling)
+
 ## [1.4.1] - 2018-10-13
 
 - [#417](https://github.com/oauth-xx/oauth2/pull/417) - update jwt dependency (@thewoolleyman)

From 003a458331d8ed128d2449c5bfaaf558f40337c5 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Tue, 1 Oct 2019 03:44:44 -0600
Subject: [PATCH 004/163] document new Ruby support

---
 CHANGELOG.md | 1 +
 1 file changed, 1 insertion(+)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 58796f91..a1753d3d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,6 +8,7 @@ All notable changes to this project will be documented in this file.
 ## [1.4.2] - 2019-10-01
 
 - [#478](https://github.com/oauth-xx/oauth2/pull/478) - support latest version of faraday & fix build (@pboling)
+  - officially support Ruby 2.6 and truffleruby
 
 ## [1.4.1] - 2018-10-13
 

From 2a8e10a463290eb6dc9ab0f9fc22c49769f0dcac Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Tue, 1 Oct 2019 03:52:19 -0600
Subject: [PATCH 005/163] Update support matrix

---
 README.md | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/README.md b/README.md
index 77054ded..06140a83 100644
--- a/README.md
+++ b/README.md
@@ -129,7 +129,7 @@ requests for tokens for any Authentication grant type.
 This library aims to support and is [tested against][travis] the following Ruby
 implementations:
 
-### Rubies with support ending at Oauth2 2.x
+### Rubies with support ending at Oauth2 1.x
 
 * Ruby 1.9.3
 * Ruby 2.0.0
@@ -145,13 +145,16 @@ implementations:
 * Ruby 2.3 - Support through version 3.x series
 * Ruby 2.4
 * Ruby 2.5
+* Ruby 2.6
 * [JRuby 9.1][jruby-9.1] (targets MRI v2.3) 
 * [JRuby 9.2][jruby-9.2] (targets MRI v2.5)
+* [truffleruby][truffleruby] (targets MRI 2.5)
 
 [jruby-1.7]: https://www.jruby.org/2017/05/11/jruby-1-7-27.html
 [jruby-9.0]: https://www.jruby.org/2016/01/26/jruby-9-0-5-0.html
 [jruby-9.1]: https://www.jruby.org/2017/05/16/jruby-9-1-9-0.html
 [jruby-9.2]: https://www.jruby.org/2018/05/24/jruby-9-2-0-0.html
+[truffleruby]: https://github.com/oracle/truffleruby
 
 If something doesn't work on one of these interpreters, it's a bug.
 

From a71cd2e003763014370bfee7e1d1a44a54ca4390 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Tue, 1 Oct 2019 03:56:19 -0600
Subject: [PATCH 006/163] Fix support matrix to include continued support for
 Ruby 2.2

---
 README.md | 21 +++++++++++----------
 1 file changed, 11 insertions(+), 10 deletions(-)

diff --git a/README.md b/README.md
index 06140a83..fe8f83c8 100644
--- a/README.md
+++ b/README.md
@@ -132,23 +132,24 @@ implementations:
 ### Rubies with support ending at Oauth2 1.x
 
 * Ruby 1.9.3
+  - [JRuby 1.7][jruby-1.7] (targets MRI v1.9)
+
 * Ruby 2.0.0
+  - [JRuby 9.0][jruby-9.0] (targets MRI v2.0)
 * Ruby 2.1
-* Ruby 2.2
-* [JRuby 1.7][jruby-1.7] (targets MRI v1.9)
-* [JRuby 9.0][jruby-9.0] (targets MRI v2.0)
 
 ---
 
 ### Rubies with continued support past Oauth2 2.x
 
-* Ruby 2.3 - Support through version 3.x series
-* Ruby 2.4
-* Ruby 2.5
-* Ruby 2.6
-* [JRuby 9.1][jruby-9.1] (targets MRI v2.3) 
-* [JRuby 9.2][jruby-9.2] (targets MRI v2.5)
-* [truffleruby][truffleruby] (targets MRI 2.5)
+* Ruby 2.2 - Support ends with version 2.x series
+* Ruby 2.3 - Support ends with version 3.x series
+  - [JRuby 9.1][jruby-9.1] (targets MRI v2.3) 
+* Ruby 2.4 - Support ends with version 4.x series
+* Ruby 2.5 - Support ends with version 5.x series
+  - [JRuby 9.2][jruby-9.2] (targets MRI v2.5)
+  - [truffleruby][truffleruby] (targets MRI 2.5)
+* Ruby 2.6 - Support ends with version 6.x series
 
 [jruby-1.7]: https://www.jruby.org/2017/05/11/jruby-1-7-27.html
 [jruby-9.0]: https://www.jruby.org/2016/01/26/jruby-9-0-5-0.html

From 889bced24bd398d1a3962c349c0ae0b1ca314185 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Tue, 1 Oct 2019 04:03:05 -0600
Subject: [PATCH 007/163] Bump version

---
 lib/oauth2/version.rb | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/oauth2/version.rb b/lib/oauth2/version.rb
index 6b63a98c..1cdc1cd6 100644
--- a/lib/oauth2/version.rb
+++ b/lib/oauth2/version.rb
@@ -20,7 +20,7 @@ def minor
     #
     # @return [Integer]
     def patch
-      1
+      2
     end
 
     # The pre-release version, if any

From 0fbb930e6faeb71d0d11f8700c311a36b2ec791f Mon Sep 17 00:00:00 2001
From: Peter Boling <45861765+galtzo@users.noreply.github.com>
Date: Tue, 1 Oct 2019 10:32:59 -0600
Subject: [PATCH 008/163] Link for 1.4.1...1.4.2 changeset

---
 CHANGELOG.md | 1 +
 1 file changed, 1 insertion(+)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index a1753d3d..b718811c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -141,4 +141,5 @@ All notable changes to this project will be documented in this file.
 [1.3.1]: https://github.com/oauth-xx/oauth2/compare/v1.3.0...v1.3.1
 [1.4.0]: https://github.com/oauth-xx/oauth2/compare/v1.3.1...v1.4.0
 [1.4.1]: https://github.com/oauth-xx/oauth2/compare/v1.4.0...v1.4.1
+[1.4.2]: https://github.com/oauth-xx/oauth2/compare/v1.4.1...v1.4.2
 [unreleased]: https://github.com/oauth-xx/oauth2/compare/v1.4.1...HEAD

From 0bb94ba09945b137ca72048cd1cdf5ff10a157fa Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Tue, 1 Oct 2019 10:46:12 -0600
Subject: [PATCH 009/163] Update intridea links to oauth-xx

---
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.md b/README.md
index fe8f83c8..870227a9 100644
--- a/README.md
+++ b/README.md
@@ -4,7 +4,7 @@
 [![Total Downloads](https://img.shields.io/gem/dt/oauth2.svg)][gem]
 [![Downloads Today](https://img.shields.io/gem/rt/oauth2.svg)][gem]
 [![Build Status](https://travis-ci.org/oauth-xx/oauth2.svg?branch=1-4-stable)][travis]
-[![Coverage Status](http://img.shields.io/coveralls/intridea/oauth2.svg)][coveralls]
+[![Coverage Status](http://img.shields.io/coveralls/oauth-xx/oauth2.svg)][coveralls]
 [![Maintainability](https://api.codeclimate.com/v1/badges/688c612528ff90a46955/maintainability)][codeclimate-maintainability]
 [![Depfu](https://badges.depfu.com/badges/6d34dc1ba682bbdf9ae2a97848241743/count.svg)][depfu]
 [![Open Source Helpers](https://www.codetriage.com/oauth-xx/oauth2/badges/users.svg)][code-triage]

From 197e1e76af15e251f0be6e879b878c4fa116f413 Mon Sep 17 00:00:00 2001
From: Stephen Reid <stephen.reid@freeagent.com>
Date: Mon, 27 Jan 2020 14:55:33 +0000
Subject: [PATCH 010/163] add support for private_key_jwt and tls_client_auth

fix incorrect assertion in authenticator_spec

updates expected debugging output to include INFO instead of DEBUG

reduces specificity of test on debug output to allow for the difference between ruby versions

corrects text for authenticator_spec

Updates comments in authenticator to reflect apply_client_id not being used for private_key_jwt
---
 lib/oauth2/authenticator.rb       | 10 ++++++++++
 spec/oauth2/authenticator_spec.rb | 18 ++++++++++++++++++
 spec/oauth2/client_spec.rb        |  6 +++---
 3 files changed, 31 insertions(+), 3 deletions(-)

diff --git a/lib/oauth2/authenticator.rb b/lib/oauth2/authenticator.rb
index ce627920..6194b837 100644
--- a/lib/oauth2/authenticator.rb
+++ b/lib/oauth2/authenticator.rb
@@ -25,6 +25,10 @@ def apply(params)
         apply_basic_auth(params)
       when :request_body
         apply_params_auth(params)
+      when :tls_client_auth
+        apply_client_id(params)
+      when :private_key_jwt
+        params
       else
         raise NotImplementedError
       end
@@ -42,6 +46,12 @@ def apply_params_auth(params)
       {'client_id' => id, 'client_secret' => secret}.merge(params)
     end
 
+    # When using schemes that don't require the client_secret to be passed i.e TLS Client Auth,
+    # we don't want to send the secret
+    def apply_client_id(params)
+      { 'client_id' => id }.merge(params)
+    end
+
     # Adds an `Authorization` header with Basic Auth credentials if and only if
     # it is not already set in the params.
     def apply_basic_auth(params)
diff --git a/spec/oauth2/authenticator_spec.rb b/spec/oauth2/authenticator_spec.rb
index 49838da3..e4d60482 100644
--- a/spec/oauth2/authenticator_spec.rb
+++ b/spec/oauth2/authenticator_spec.rb
@@ -38,6 +38,24 @@
           :headers => {'A' => 'b'}
         )
       end
+
+      context 'using tls client authentication' do
+        let(:mode) { :tls_client_auth }
+
+        it 'does not add client_secret' do
+          output = subject.apply({})
+          expect(output).to eq('client_id' => 'foo')
+        end
+      end
+
+      context 'using private key jwt authentication' do
+        let(:mode) { :private_key_jwt }
+
+        it 'does not add client_secret or client_id' do
+          output = subject.apply({})
+          expect(output).to eq({})
+        end
+      end
     end
 
     context 'with Basic authentication' do
diff --git a/spec/oauth2/client_spec.rb b/spec/oauth2/client_spec.rb
index 464a5b5a..62cb4ec2 100644
--- a/spec/oauth2/client_spec.rb
+++ b/spec/oauth2/client_spec.rb
@@ -251,9 +251,9 @@
           subject.request(:get, '/success')
         end
         logs = [
-          'INFO -- request: GET https://api.example.com/success',
-          'INFO -- response: Status 200',
-          'DEBUG -- response: Content-Type: "text/awesome"'
+          '-- request: GET https://api.example.com/success',
+          '-- response: Status 200',
+          '-- response: Content-Type: "text/awesome"'
         ]
         expect(output).to include(*logs)
       end

From 376b7ff9d22a1dc9a19996009e1ef84bda41d470 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Tue, 28 Jan 2020 15:23:59 -0800
Subject: [PATCH 011/163] Switch to latest Ruby for local dev

---
 .ruby-version | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.ruby-version b/.ruby-version
index ec1cf33c..24ba9a38 100644
--- a/.ruby-version
+++ b/.ruby-version
@@ -1 +1 @@
-2.6.3
+2.7.0

From e091c5d63aa6c38fc72abf1f60bc4bc3888ed079 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Tue, 28 Jan 2020 22:11:53 -0800
Subject: [PATCH 012/163] Add Ruby 2.7.0 to build

---
 .travis.yml               | 2 ++
 gemfiles/ruby_2.7.gemfile | 9 +++++++++
 2 files changed, 11 insertions(+)
 create mode 100644 gemfiles/ruby_2.7.gemfile

diff --git a/.travis.yml b/.travis.yml
index 9538619d..ba251e56 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -60,6 +60,8 @@ matrix:
       gemfile: gemfiles/ruby_2.5.gemfile
     - rvm: 2.6
       gemfile: gemfiles/ruby_2.6.gemfile
+    - rvm: 2.7
+      gemfile: gemfiles/ruby_2.7.gemfile
     - rvm: jruby-head
       gemfile: gemfiles/jruby_head.gemfile
     - rvm: ruby-head
diff --git a/gemfiles/ruby_2.7.gemfile b/gemfiles/ruby_2.7.gemfile
new file mode 100644
index 00000000..822e2f2c
--- /dev/null
+++ b/gemfiles/ruby_2.7.gemfile
@@ -0,0 +1,9 @@
+source 'https://rubygems.org'
+
+group :development do
+  gem 'pry'
+  gem 'byebug'
+  gem 'pry-byebug'
+end
+
+gemspec :path => '../'

From e74cb519c59eeac09efb3f469af544d3b39350f9 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Tue, 28 Jan 2020 23:00:07 -0800
Subject: [PATCH 013/163] Add CodeClimate test reporter

---
 .travis.yml | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/.travis.yml b/.travis.yml
index ba251e56..6c42320f 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -19,10 +19,23 @@ before_install:
       gem install --no-document bundler "bundler:>=2.0"
     fi
 
+before_script:
+  - curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
+  - chmod +x ./cc-test-reporter
+  - ./cc-test-reporter before-build
+
+after_script:
+  - ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT
+
 bundler_args: --no-deployment --jobs 3 --retry 3
 
 cache: bundler
 
+env:
+  global:
+    - JRUBY_OPTS="$JRUBY_OPTS -Xcli.debug=true --debug"
+    - CC_TEST_REPORTER_ID=29caf9cf27d27ae609c088feb9d4ba34460f7a39251f2e8615c9a16f3075530e
+
 language: ruby
 
 matrix:

From 230a6079b9c0c135c8fd005fda61c267b324dd3d Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Tue, 28 Jan 2020 23:05:44 -0800
Subject: [PATCH 014/163] Allow jruby-9.2 to fail because it fails to download
 constantly

---
 .travis.yml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/.travis.yml b/.travis.yml
index 6c42320f..53dd0e49 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -44,6 +44,7 @@ matrix:
     - rvm: ruby-head
     - rvm: truffleruby
     - rvm: jruby-9.0
+    - rvm: jruby-9.2 # jruby-9.2 often fails to download, thus failing the build.
   fast_finish: true
   include:
 #    - rvm: jruby-1.7 # targets MRI v1.9

From 1d9a3d8d84d45e419b8ba65557c94ee8c2ba00e0 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Tue, 28 Jan 2020 23:11:45 -0800
Subject: [PATCH 015/163] New code coverage badge

---
 README.md | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/README.md b/README.md
index 870227a9..dfa70295 100644
--- a/README.md
+++ b/README.md
@@ -4,7 +4,7 @@
 [![Total Downloads](https://img.shields.io/gem/dt/oauth2.svg)][gem]
 [![Downloads Today](https://img.shields.io/gem/rt/oauth2.svg)][gem]
 [![Build Status](https://travis-ci.org/oauth-xx/oauth2.svg?branch=1-4-stable)][travis]
-[![Coverage Status](http://img.shields.io/coveralls/oauth-xx/oauth2.svg)][coveralls]
+[![Test Coverage](https://api.codeclimate.com/v1/badges/688c612528ff90a46955/test_coverage)][codeclimate-coverage]
 [![Maintainability](https://api.codeclimate.com/v1/badges/688c612528ff90a46955/maintainability)][codeclimate-maintainability]
 [![Depfu](https://badges.depfu.com/badges/6d34dc1ba682bbdf9ae2a97848241743/count.svg)][depfu]
 [![Open Source Helpers](https://www.codetriage.com/oauth-xx/oauth2/badges/users.svg)][code-triage]
@@ -16,6 +16,7 @@
 [travis]: http://travis-ci.org/oauth-xx/oauth2
 [coveralls]: https://coveralls.io/r/oauth-xx/oauth2
 [codeclimate-maintainability]: https://codeclimate.com/github/oauth-xx/oauth2/maintainability
+[codeclimate-coverage]: https://codeclimate.com/github/oauth-xx/oauth2/test_coverage
 [depfu]: https://depfu.com/github/oauth-xx/oauth2
 [source-license]: https://opensource.org/licenses/MIT
 [inch-ci]: http://inch-ci.org/github/oauth-xx/oauth2

From fa95a44884aaf00cba0dbfaff7450437e73591de Mon Sep 17 00:00:00 2001
From: asm__ <660363+asm256@users.noreply.github.com>
Date: Thu, 15 Nov 2018 17:00:36 +0900
Subject: [PATCH 016/163] spec #432

---
 spec/oauth2/access_token_spec.rb | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/spec/oauth2/access_token_spec.rb b/spec/oauth2/access_token_spec.rb
index ad53b2ac..50dd660e 100644
--- a/spec/oauth2/access_token_spec.rb
+++ b/spec/oauth2/access_token_spec.rb
@@ -12,6 +12,7 @@
         VERBS.each do |verb|
           stub.send(verb, '/token/header') { |env| [200, {}, env[:request_headers]['Authorization']] }
           stub.send(verb, "/token/query?access_token=#{token}") { |env| [200, {}, Addressable::URI.parse(env[:url]).query_values['access_token']] }
+          stub.send(verb, '/token/query_string') { |env| [200, {}, CGI.unescape(Addressable::URI.parse(env[:url]).query)] }
           stub.send(verb, '/token/body') { |env| [200, {}, env[:body]] }
         end
         stub.post('/oauth/token') { |env| [200, {'Content-Type' => 'application/json'}, refresh_body] }
@@ -101,6 +102,11 @@ def assert_initialized_token(target) # rubocop:disable Metrics/AbcSize
         it "sends the token in the Authorization header for a #{verb.to_s.upcase} request" do
           expect(subject.post('/token/query').body).to eq(token)
         end
+
+        it "sends a #{verb.to_s.upcase} request and options[:param_name] include [number]." do
+          subject.options[:param_name] = 'auth[1]'
+          expect(subject.__send__(verb, '/token/query_string').body).to include("auth[1]=#{token}")
+        end
       end
     end
 
@@ -115,6 +121,14 @@ def assert_initialized_token(target) # rubocop:disable Metrics/AbcSize
         end
       end
     end
+
+    context "params include [number]" do
+      VERBS.each do |verb|
+        it "sends #{verb.to_s.upcase} correct query" do
+          expect(subject.__send__(verb, '/token/query_string', :params => {'foo[bar][1]' => 'val'}).body).to include('foo[bar][1]=val')
+        end
+      end
+    end
   end
 
   describe '#expires?' do

From d8c7005574d4cb36c3b0970f61aca0f4340e205b Mon Sep 17 00:00:00 2001
From: asm__ <660363+asm256@users.noreply.github.com>
Date: Thu, 15 Nov 2018 17:27:07 +0900
Subject: [PATCH 017/163] fix OAuth2::Client#request

If field name with brackets and numbers in params options,
request will send an incorrect query.
---
 lib/oauth2/client.rb | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/lib/oauth2/client.rb b/lib/oauth2/client.rb
index 356f93e7..b3780223 100644
--- a/lib/oauth2/client.rb
+++ b/lib/oauth2/client.rb
@@ -94,9 +94,10 @@ def token_url(params = nil)
     def request(verb, url, opts = {}) # rubocop:disable CyclomaticComplexity, MethodLength, Metrics/AbcSize
       connection.response :logger, ::Logger.new($stdout) if ENV['OAUTH_DEBUG'] == 'true'
 
-      url = connection.build_url(url, opts[:params]).to_s
+      url = connection.build_url(url).to_s
 
       response = connection.run_request(verb, url, opts[:body], opts[:headers]) do |req|
+        req.params.update(opts[:params]) if opts[:params]
         yield(req) if block_given?
       end
       response = Response.new(response, :parse => opts[:parse])
@@ -130,7 +131,7 @@ def request(verb, url, opts = {}) # rubocop:disable CyclomaticComplexity, Method
     # @param [Hash] params a Hash of params for the token endpoint
     # @param [Hash] access token options, to pass to the AccessToken object
     # @param [Class] class of access token for easier subclassing OAuth2::AccessToken
-    # @return [AccessToken] the initalized AccessToken
+    # @return [AccessToken] the initialized AccessToken
     def get_token(params, access_token_opts = {}, access_token_class = AccessToken) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
       params = Authenticator.new(id, secret, options[:auth_scheme]).apply(params)
       opts = {:raise_errors => options[:raise_errors], :parse => params.delete(:parse)}

From cf8d08202779a0d8af8d72132891c44abb7886f7 Mon Sep 17 00:00:00 2001
From: asm__ <660363+asm256@users.noreply.github.com>
Date: Thu, 15 Nov 2018 17:54:02 +0900
Subject: [PATCH 018/163] shaping code

---
 spec/oauth2/access_token_spec.rb | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/spec/oauth2/access_token_spec.rb b/spec/oauth2/access_token_spec.rb
index 50dd660e..b2743aed 100644
--- a/spec/oauth2/access_token_spec.rb
+++ b/spec/oauth2/access_token_spec.rb
@@ -122,7 +122,7 @@ def assert_initialized_token(target) # rubocop:disable Metrics/AbcSize
       end
     end
 
-    context "params include [number]" do
+    context 'params include [number]' do
       VERBS.each do |verb|
         it "sends #{verb.to_s.upcase} correct query" do
           expect(subject.__send__(verb, '/token/query_string', :params => {'foo[bar][1]' => 'val'}).body).to include('foo[bar][1]=val')

From fc7c36c86c29eabc5c01c7601b08a2b51a2dfd78 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Wed, 29 Jan 2020 00:18:42 -0800
Subject: [PATCH 019/163] jruby 9.1 often fails to download

---
 .travis.yml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/.travis.yml b/.travis.yml
index 53dd0e49..6c65fe29 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -44,6 +44,7 @@ matrix:
     - rvm: ruby-head
     - rvm: truffleruby
     - rvm: jruby-9.0
+    - rvm: jruby-9.1 # jruby-9.1 often fails to download, thus failing the build.
     - rvm: jruby-9.2 # jruby-9.2 often fails to download, thus failing the build.
   fast_finish: true
   include:

From 6a177a33f265d547e6cc1fc7b62e18d725322a9f Mon Sep 17 00:00:00 2001
From: Orien Madgwick <_@orien.io>
Date: Sat, 5 Oct 2019 10:34:30 +1000
Subject: [PATCH 020/163] Add project metadata to the gemspec

As per https://guides.rubygems.org/specification-reference/#metadata,
add metadata to the gemspec file. This'll allow people to more easily
access the source code, raise issues and read the changelog. These
`bug_tracker_uri`, `changelog_uri`, `documentation_uri`, `wiki_uri` and
`source_code_uri` links will appear on the rubygems page at
https://rubygems.org/gems/oauth2 and be available via the rubygems API
after the next release.
---
 oauth2.gemspec | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/oauth2.gemspec b/oauth2.gemspec
index be52c417..1e8b8aa1 100644
--- a/oauth2.gemspec
+++ b/oauth2.gemspec
@@ -22,6 +22,14 @@ Gem::Specification.new do |spec|
   spec.summary       = 'A Ruby wrapper for the OAuth 2.0 protocol.'
   spec.version       = OAuth2::Version
 
+  spec.metadata = {
+    'bug_tracker_uri'   => 'https://github.com/oauth-xx/oauth2/issues',
+    'changelog_uri'     => "https://github.com/oauth-xx/oauth2/blob/v#{spec.version}/CHANGELOG.md",
+    'documentation_uri' => "https://www.rubydoc.info/gems/oauth2/#{spec.version}",
+    'source_code_uri'   => "https://github.com/oauth-xx/oauth2/tree/v#{spec.version}",
+    'wiki_uri'          => 'https://github.com/oauth-xx/oauth2/wiki'
+  }
+
   spec.require_paths = %w[lib]
   spec.bindir        = 'exe'
   spec.executables   = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }

From aac36d692df3a9dc9aab1895c26c48a2e846bc77 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Wed, 29 Jan 2020 00:40:54 -0800
Subject: [PATCH 021/163] Prepare for 1.4.3 release

---
 CHANGELOG.md | 7 +++++++
 README.md    | 1 +
 2 files changed, 8 insertions(+)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index b718811c..8228331a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
 
 - no changes yet
 
+## [1.4.3] - 2020-01-29
+
+- [#483](https://github.com/oauth-xx/oauth2/pull/483) - add project metadata to gemspec (@orien)
+- [#495](https://github.com/oauth-xx/oauth2/pull/495) - support additional types of access token requests (@SteveyblamFreeagent, @thomcorley, @dgholz)
+  - Adds support for private_key_jwt and tls_client_auth
+
 ## [1.4.2] - 2019-10-01
 
 - [#478](https://github.com/oauth-xx/oauth2/pull/478) - support latest version of faraday & fix build (@pboling)
@@ -142,4 +148,5 @@ All notable changes to this project will be documented in this file.
 [1.4.0]: https://github.com/oauth-xx/oauth2/compare/v1.3.1...v1.4.0
 [1.4.1]: https://github.com/oauth-xx/oauth2/compare/v1.4.0...v1.4.1
 [1.4.2]: https://github.com/oauth-xx/oauth2/compare/v1.4.1...v1.4.2
+[1.4.3]: https://github.com/oauth-xx/oauth2/compare/v1.4.2...v1.4.3
 [unreleased]: https://github.com/oauth-xx/oauth2/compare/v1.4.1...HEAD
diff --git a/README.md b/README.md
index dfa70295..bbc568e0 100644
--- a/README.md
+++ b/README.md
@@ -151,6 +151,7 @@ implementations:
   - [JRuby 9.2][jruby-9.2] (targets MRI v2.5)
   - [truffleruby][truffleruby] (targets MRI 2.5)
 * Ruby 2.6 - Support ends with version 6.x series
+* Ruby 2.7 - Support ends with version 7.x series
 
 [jruby-1.7]: https://www.jruby.org/2017/05/11/jruby-1-7-27.html
 [jruby-9.0]: https://www.jruby.org/2016/01/26/jruby-9-0-5-0.html

From cb4619c57c07c0f78c3e2136511e51f1ea24a2c8 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Wed, 29 Jan 2020 00:43:29 -0800
Subject: [PATCH 022/163] Prepare for 1.4.3 release

---
 README.md | 22 +++++++++++++++++++++-
 1 file changed, 21 insertions(+), 1 deletion(-)

diff --git a/README.md b/README.md
index bbc568e0..53e9d1ee 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,20 @@
 # OAuth2
 
+If you need the readme for a released version of the gem please find it below:
+
+| Version  | Release Date | Readme                                                   |
+|----------|--------------|----------------------------------------------------------|
+| 1.4.3    | Jan 29, 2020 | https://github.com/oauth-xx/oauth2/blob/v1.4.3/README.md |
+| 1.4.2    | Oct 1, 2019  | https://github.com/oauth-xx/oauth2/blob/v1.4.2/README.md |
+| 1.4.1    | Oct 13, 2018 | https://github.com/oauth-xx/oauth2/blob/v1.4.1/README.md |
+| 1.4.0    | Jun 9, 2017  | https://github.com/oauth-xx/oauth2/blob/v1.4.0/README.md |
+| 1.3.1    | Mar 3, 2017  | https://github.com/oauth-xx/oauth2/blob/v1.3.1/README.md |
+| 1.3.0    | Dec 27, 2016 | https://github.com/oauth-xx/oauth2/blob/v1.3.0/README.md |
+| 1.2.0    | Jun 30, 2016 | https://github.com/oauth-xx/oauth2/blob/v1.2.0/README.md |
+| 1.1.0    | Jan 30, 2016 | https://github.com/oauth-xx/oauth2/blob/v1.1.0/README.md |
+| 1.0.0    | May 23, 2014 | https://github.com/oauth-xx/oauth2/blob/v1.0.0/README.md |
+| < 1.0.0  | Find here    | https://github.com/oauth-xx/oauth2/tags                  |
+
 [![Gem Version](http://img.shields.io/gem/v/oauth2.svg)][gem]
 [![Total Downloads](https://img.shields.io/gem/dt/oauth2.svg)][gem]
 [![Downloads Today](https://img.shields.io/gem/rt/oauth2.svg)][gem]
@@ -21,6 +36,7 @@
 [source-license]: https://opensource.org/licenses/MIT
 [inch-ci]: http://inch-ci.org/github/oauth-xx/oauth2
 [code-triage]: https://www.codetriage.com/oauth-xx/oauth2
+[fossa1]: https://app.fossa.io/projects/git%2Bgithub.com%2Foauth-xx%2Foauth2?ref=badge_shield
 
 A Ruby wrapper for the [OAuth 2.0 specification][oauth2-spec].
 
@@ -50,7 +66,7 @@ Or install it yourself as:
 
 [code]: https://github.com/oauth-xx/oauth2
 [issues]: https://github.com/oauth-xx/oauth2/issues
-[wiki]: https://github.com/oauth-xx/oauth2/wiki
+[wiki]: https://wiki.github.com/oauth-xx/oauth2
 
 ## Usage Examples
 
@@ -67,6 +83,7 @@ response.class.name
 # => OAuth2::Response
 ```
 ## OAuth2::Response
+
 The AccessToken methods #get, #post, #put and #delete and the generic #request
 will return an instance of the #OAuth2::Response class.
 
@@ -79,12 +96,14 @@ The original response body, headers, and status can be accessed via their
 respective methods.
 
 ## OAuth2::AccessToken
+
 If you have an existing Access Token for a user, you can initialize an instance
 using various class methods including the standard new, from_hash (if you have
 a hash of the values), or from_kvform (if you have an
 application/x-www-form-urlencoded encoded string of the values).
 
 ## OAuth2::Error
+
 On 400+ status code responses, an OAuth2::Error will be raised.  If it is a
 standard OAuth2 error response, the body will be parsed and #code and #description will contain the values provided from the error and
 error_description parameters.  The #response property of OAuth2::Error will
@@ -96,6 +115,7 @@ instance will be returned as usual and on 400+ status code responses, the
 Response instance will contain the OAuth2::Error instance.
 
 ## Authorization Grants
+
 Currently the Authorization Code, Implicit, Resource Owner Password Credentials, Client Credentials, and Assertion
 authentication grant types have helper strategy classes that simplify client
 use.  They are available via the #auth_code, #implicit, #password, #client_credentials, and #assertion methods respectively.

From 6e4c179285ee9ba2516a6724b59289d7deefb0aa Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Wed, 29 Jan 2020 00:58:38 -0800
Subject: [PATCH 023/163] Correct unreleased version number

---
 lib/oauth2/version.rb | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/oauth2/version.rb b/lib/oauth2/version.rb
index 1cdc1cd6..9b02e785 100644
--- a/lib/oauth2/version.rb
+++ b/lib/oauth2/version.rb
@@ -20,7 +20,7 @@ def minor
     #
     # @return [Integer]
     def patch
-      2
+      3
     end
 
     # The pre-release version, if any

From 32b7084efe1fcfe5b49a892dbcaff28036797adc Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Wed, 5 Feb 2020 19:10:35 -0800
Subject: [PATCH 024/163] Document fix included in 1.4.3 release

- [#433](https://github.com/oauth-xx/oauth2/pull/433) - allow field names with square brackets and numbers in params (@asm256)
---
 CHANGELOG.md | 1 +
 1 file changed, 1 insertion(+)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8228331a..b02ed346 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -10,6 +10,7 @@ All notable changes to this project will be documented in this file.
 - [#483](https://github.com/oauth-xx/oauth2/pull/483) - add project metadata to gemspec (@orien)
 - [#495](https://github.com/oauth-xx/oauth2/pull/495) - support additional types of access token requests (@SteveyblamFreeagent, @thomcorley, @dgholz)
   - Adds support for private_key_jwt and tls_client_auth
+- [#433](https://github.com/oauth-xx/oauth2/pull/433) - allow field names with square brackets and numbers in params (@asm256)
 
 ## [1.4.2] - 2019-10-01
 

From 8a2bd99c05cec80276614b5f10d7798d0f880da7 Mon Sep 17 00:00:00 2001
From: Lomey <bohdanlomey@gmail.com>
Date: Tue, 11 Sep 2018 22:11:08 +0300
Subject: [PATCH 025/163] Fixed epires_at for formatted time

---
 lib/oauth2/access_token.rb       | 9 ++++++++-
 spec/oauth2/access_token_spec.rb | 4 +++-
 2 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/lib/oauth2/access_token.rb b/lib/oauth2/access_token.rb
index 1b178390..2156753d 100644
--- a/lib/oauth2/access_token.rb
+++ b/lib/oauth2/access_token.rb
@@ -46,7 +46,7 @@ def initialize(client, token, opts = {}) # rubocop:disable Metrics/AbcSize
       end
       @expires_in ||= opts.delete('expires')
       @expires_in &&= @expires_in.to_i
-      @expires_at &&= @expires_at.to_i
+      @expires_at &&= convert_expires_at(@expires_at)
       @expires_at ||= Time.now.to_i + @expires_in if @expires_in
       @options = {:mode          => opts.delete(:mode) || :header,
                   :header_format => opts.delete(:header_format) || 'Bearer %s',
@@ -169,5 +169,12 @@ def configure_authentication!(opts) # rubocop:disable MethodLength, Metrics/AbcS
         raise("invalid :mode option of #{options[:mode]}")
       end
     end
+
+    def convert_expires_at(expires_at)
+      expires_at_i = expires_at.to_i
+      return expires_at_i if expires_at_i > Time.now.utc.to_i
+      return Time.parse(expires_at).to_i if expires_at.is_a?(String)
+      expires_at_i
+    end
   end
 end
diff --git a/spec/oauth2/access_token_spec.rb b/spec/oauth2/access_token_spec.rb
index b2743aed..cb3f45f3 100644
--- a/spec/oauth2/access_token_spec.rb
+++ b/spec/oauth2/access_token_spec.rb
@@ -73,10 +73,12 @@ def assert_initialized_token(target) # rubocop:disable Metrics/AbcSize
     end
 
     it 'initializes with a string expires_at' do
-      hash = {:access_token => token, :expires_at => '1361396829', 'foo' => 'bar'}
+      future = Time.now.utc + 100_000
+      hash = {:access_token => token, :expires_at => future.iso8601, 'foo' => 'bar'}
       target = described_class.from_hash(client, hash)
       assert_initialized_token(target)
       expect(target.expires_at).to be_a(Integer)
+      expect(target.expires_at).to eql(future.to_i)
     end
   end
 

From de05368a3ac825496a6b8126412c84db8d760429 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Wed, 12 Feb 2020 16:03:55 -0800
Subject: [PATCH 026/163] CHANGELOG for 1.4.4 release

---
 CHANGELOG.md | 4 ++++
 README.md    | 1 +
 2 files changed, 5 insertions(+)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index b02ed346..e8303128 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,10 @@ All notable changes to this project will be documented in this file.
 
 - no changes yet
 
+## [1.4.4] - 2020-02-12
+
+- [#408](https://github.com/oauth-xx/oauth2/pull/408) - Fixed expires_at for formatted time (@Lomey)
+
 ## [1.4.3] - 2020-01-29
 
 - [#483](https://github.com/oauth-xx/oauth2/pull/483) - add project metadata to gemspec (@orien)
diff --git a/README.md b/README.md
index 53e9d1ee..55ea4d88 100644
--- a/README.md
+++ b/README.md
@@ -4,6 +4,7 @@ If you need the readme for a released version of the gem please find it below:
 
 | Version  | Release Date | Readme                                                   |
 |----------|--------------|----------------------------------------------------------|
+| 1.4.4    | Feb 12, 2020 | https://github.com/oauth-xx/oauth2/blob/v1.4.4/README.md |
 | 1.4.3    | Jan 29, 2020 | https://github.com/oauth-xx/oauth2/blob/v1.4.3/README.md |
 | 1.4.2    | Oct 1, 2019  | https://github.com/oauth-xx/oauth2/blob/v1.4.2/README.md |
 | 1.4.1    | Oct 13, 2018 | https://github.com/oauth-xx/oauth2/blob/v1.4.1/README.md |

From cb8eca28ec8b831833199cb4e60014cfc0bc4ac0 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Wed, 12 Feb 2020 16:04:09 -0800
Subject: [PATCH 027/163] Update version to 1.4.4

---
 lib/oauth2/version.rb | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/oauth2/version.rb b/lib/oauth2/version.rb
index 9b02e785..684cdcfc 100644
--- a/lib/oauth2/version.rb
+++ b/lib/oauth2/version.rb
@@ -20,7 +20,7 @@ def minor
     #
     # @return [Integer]
     def patch
-      3
+      4
     end
 
     # The pre-release version, if any

From edb9fb9837a14143fddc5498da2c69e571754ef1 Mon Sep 17 00:00:00 2001
From: An Vo <thien.an.vo.nguyen@gmail.com>
Date: Wed, 1 Jul 2020 02:38:25 +0700
Subject: [PATCH 028/163] Fix missing custom headers in get_token (#512)

* Add test and work around for #498 - lost custom headers

* Remove activesupport. Patch string headers in get_token

* Introduce special param keys

* Replace .transform_keys by .map for older version of ruby
---
 lib/oauth2/client.rb       | 12 +++++++-
 spec/oauth2/client_spec.rb | 62 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 73 insertions(+), 1 deletion(-)

diff --git a/lib/oauth2/client.rb b/lib/oauth2/client.rb
index b3780223..b715e2d0 100644
--- a/lib/oauth2/client.rb
+++ b/lib/oauth2/client.rb
@@ -4,6 +4,8 @@
 module OAuth2
   # The OAuth2::Client class
   class Client # rubocop:disable Metrics/ClassLength
+    RESERVED_PARAM_KEYS = ['headers', 'parse'].freeze
+
     attr_reader :id, :secret, :site
     attr_accessor :options
     attr_writer :connection
@@ -132,7 +134,15 @@ def request(verb, url, opts = {}) # rubocop:disable CyclomaticComplexity, Method
     # @param [Hash] access token options, to pass to the AccessToken object
     # @param [Class] class of access token for easier subclassing OAuth2::AccessToken
     # @return [AccessToken] the initialized AccessToken
-    def get_token(params, access_token_opts = {}, access_token_class = AccessToken) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
+    def get_token(params, access_token_opts = {}, access_token_class = AccessToken) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
+      params = params.map do |key, value|
+        if RESERVED_PARAM_KEYS.include?(key)
+          [key.to_sym, value]
+        else
+          [key, value]
+        end
+      end.to_h
+
       params = Authenticator.new(id, secret, options[:auth_scheme]).apply(params)
       opts = {:raise_errors => options[:raise_errors], :parse => params.delete(:parse)}
       headers = params.delete(:headers) || {}
diff --git a/spec/oauth2/client_spec.rb b/spec/oauth2/client_spec.rb
index 62cb4ec2..f045e044 100644
--- a/spec/oauth2/client_spec.rb
+++ b/spec/oauth2/client_spec.rb
@@ -157,6 +157,68 @@
         client.auth_code.get_token('code')
       end
     end
+
+    describe 'custom headers' do
+      context 'string key headers' do
+        it 'adds the custom headers to request' do
+          client = described_class.new('abc', 'def', :site => 'https://api.example.com', :auth_scheme => :request_body) do |builder|
+            builder.adapter :test do |stub|
+              stub.post('/oauth/token') do |env|
+                expect(env.request_headers).to include({'CustomHeader' => 'CustomHeader'})
+                [200, {'Content-Type' => 'application/json'}, '{"access_token":"token"}']
+              end
+            end
+          end
+          header_params = {'headers' => { 'CustomHeader' => 'CustomHeader' }}
+          client.auth_code.get_token('code', header_params)
+        end
+      end
+
+      context 'symbol key headers' do
+        it 'adds the custom headers to request' do
+          client = described_class.new('abc', 'def', :site => 'https://api.example.com', :auth_scheme => :request_body) do |builder|
+            builder.adapter :test do |stub|
+              stub.post('/oauth/token') do |env|
+                expect(env.request_headers).to include({'CustomHeader' => 'CustomHeader'})
+                [200, {'Content-Type' => 'application/json'}, '{"access_token":"token"}']
+              end
+            end
+          end
+          header_params = {headers: { 'CustomHeader' => 'CustomHeader' }}
+          client.auth_code.get_token('code', header_params)
+        end
+      end
+
+      context 'string key custom headers with basic auth' do
+        it 'adds the custom headers to request' do
+          client = described_class.new('abc', 'def', :site => 'https://api.example.com') do |builder|
+            builder.adapter :test do |stub|
+              stub.post('/oauth/token') do |env|
+                expect(env.request_headers).to include({'CustomHeader' => 'CustomHeader'})
+                [200, {'Content-Type' => 'application/json'}, '{"access_token":"token"}']
+              end
+            end
+          end
+          header_params = {'headers' => { 'CustomHeader' => 'CustomHeader' }}
+          client.auth_code.get_token('code', header_params)
+        end
+      end
+
+      context 'symbol key custom headers with basic auth' do
+        it 'adds the custom headers to request' do
+          client = described_class.new('abc', 'def', :site => 'https://api.example.com') do |builder|
+            builder.adapter :test do |stub|
+              stub.post('/oauth/token') do |env|
+                expect(env.request_headers).to include({'CustomHeader' => 'CustomHeader'})
+                [200, {'Content-Type' => 'application/json'}, '{"access_token":"token"}']
+              end
+            end
+          end
+          header_params = {headers: { 'CustomHeader' => 'CustomHeader' }}
+          client.auth_code.get_token('code', header_params)
+        end
+      end
+    end
   end
 
   describe '#request' do

From b06688a76e3f3d7e54e3442a6c0e3c79d0b5cba1 Mon Sep 17 00:00:00 2001
From: anvox <thien.an.vo.nguyen@gmail.com>
Date: Wed, 1 Jul 2020 13:56:47 +0700
Subject: [PATCH 029/163] Use Hash[] for compatible back with ruby <= 2.0

---
 lib/oauth2/client.rb | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/lib/oauth2/client.rb b/lib/oauth2/client.rb
index b715e2d0..7c38e35a 100644
--- a/lib/oauth2/client.rb
+++ b/lib/oauth2/client.rb
@@ -141,7 +141,8 @@ def get_token(params, access_token_opts = {}, access_token_class = AccessToken)
         else
           [key, value]
         end
-      end.to_h
+      end
+      params = Hash[params]
 
       params = Authenticator.new(id, secret, options[:auth_scheme]).apply(params)
       opts = {:raise_errors => options[:raise_errors], :parse => params.delete(:parse)}

From d6e0598b2108e2c3a65bde173ab291baf8d34310 Mon Sep 17 00:00:00 2001
From: Jon Palmer <328224+jonspalmer@users.noreply.github.com>
Date: Thu, 16 Jul 2020 14:47:58 -0400
Subject: [PATCH 030/163] Add extract_access_token option to OAuth2::Client
 (#518)

---
 lib/oauth2/access_token.rb |   1 +
 lib/oauth2/client.rb       |  59 ++++++++++++++-----
 spec/oauth2/client_spec.rb | 116 +++++++++++++++++++++++++++++++++++++
 3 files changed, 161 insertions(+), 15 deletions(-)

diff --git a/lib/oauth2/access_token.rb b/lib/oauth2/access_token.rb
index 2156753d..656eccba 100644
--- a/lib/oauth2/access_token.rb
+++ b/lib/oauth2/access_token.rb
@@ -3,6 +3,7 @@ class AccessToken
     attr_reader :client, :token, :expires_in, :expires_at, :params
     attr_accessor :options, :refresh_token
 
+    # Should these methods be deprecated?
     class << self
       # Initializes an AccessToken from a Hash
       #
diff --git a/lib/oauth2/client.rb b/lib/oauth2/client.rb
index 7c38e35a..eb354a45 100644
--- a/lib/oauth2/client.rb
+++ b/lib/oauth2/client.rb
@@ -4,7 +4,7 @@
 module OAuth2
   # The OAuth2::Client class
   class Client # rubocop:disable Metrics/ClassLength
-    RESERVED_PARAM_KEYS = ['headers', 'parse'].freeze
+    RESERVED_PARAM_KEYS = %w[headers parse].freeze
 
     attr_reader :id, :secret, :site
     attr_accessor :options
@@ -25,8 +25,8 @@ class Client # rubocop:disable Metrics/ClassLength
     # @option opts [Symbol] :auth_scheme (:basic_auth) HTTP method to use to authorize request (:basic_auth or :request_body)
     # @option opts [Hash] :connection_opts ({}) Hash of connection options to pass to initialize Faraday with
     # @option opts [FixNum] :max_redirects (5) maximum number of redirects to follow
-    # @option opts [Boolean] :raise_errors (true) whether or not to raise an OAuth2::Error
-    #  on responses with 400+ status codes
+    # @option opts [Boolean] :raise_errors (true) whether or not to raise an OAuth2::Error on responses with 400+ status codes
+    # @option opts [Proc] :extract_access_token  proc that extracts the access token from the response
     # @yield [builder] The Faraday connection builder
     def initialize(client_id, client_secret, options = {}, &block)
       opts = options.dup
@@ -34,14 +34,18 @@ def initialize(client_id, client_secret, options = {}, &block)
       @secret = client_secret
       @site = opts.delete(:site)
       ssl = opts.delete(:ssl)
-      @options = {:authorize_url    => '/oauth/authorize',
-                  :token_url        => '/oauth/token',
-                  :token_method     => :post,
-                  :auth_scheme      => :request_body,
-                  :connection_opts  => {},
-                  :connection_build => block,
-                  :max_redirects    => 5,
-                  :raise_errors     => true}.merge(opts)
+
+      @options = {
+        :authorize_url        => '/oauth/authorize',
+        :token_url            => '/oauth/token',
+        :token_method         => :post,
+        :auth_scheme          => :request_body,
+        :connection_opts      => {},
+        :connection_build     => block,
+        :max_redirects        => 5,
+        :raise_errors         => true,
+        :extract_access_token => DEFAULT_EXTRACT_ACCESS_TOKEN
+                }.merge(opts)
       @options[:connection_opts][:ssl] = ssl if ssl
     end
 
@@ -93,7 +97,7 @@ def token_url(params = nil)
     #   code response for this request.  Will default to client option
     # @option opts [Symbol] :parse @see Response::initialize
     # @yield [req] The Faraday request
-    def request(verb, url, opts = {}) # rubocop:disable CyclomaticComplexity, MethodLength, Metrics/AbcSize
+    def request(verb, url, opts = {}) # rubocop:disable CyclomaticComplexity, MethodLength, Metrics/AbcSize, Metrics/PerceivedComplexity
       connection.response :logger, ::Logger.new($stdout) if ENV['OAUTH_DEBUG'] == 'true'
 
       url = connection.build_url(url).to_s
@@ -134,7 +138,7 @@ def request(verb, url, opts = {}) # rubocop:disable CyclomaticComplexity, Method
     # @param [Hash] access token options, to pass to the AccessToken object
     # @param [Class] class of access token for easier subclassing OAuth2::AccessToken
     # @return [AccessToken] the initialized AccessToken
-    def get_token(params, access_token_opts = {}, access_token_class = AccessToken) # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
+    def get_token(params, access_token_opts = {}, extract_access_token = options[:extract_access_token]) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/PerceivedComplexity
       params = params.map do |key, value|
         if RESERVED_PARAM_KEYS.include?(key)
           [key.to_sym, value]
@@ -156,11 +160,14 @@ def get_token(params, access_token_opts = {}, access_token_class = AccessToken)
       end
       opts[:headers].merge!(headers)
       response = request(options[:token_method], token_url, opts)
-      if options[:raise_errors] && !(response.parsed.is_a?(Hash) && response.parsed['access_token'])
+
+      access_token = build_access_token(response, access_token_opts, extract_access_token) rescue nil
+
+      if options[:raise_errors] && !access_token
         error = Error.new(response)
         raise(error)
       end
-      access_token_class.from_hash(self, response.parsed.merge(access_token_opts))
+      access_token
     end
 
     # The Authorization Code strategy
@@ -219,4 +226,26 @@ def redirection_params
       end
     end
   end
+
+  DEFAULT_EXTRACT_ACCESS_TOKEN = proc do |client, hash|
+    token = hash.delete('access_token') || hash.delete(:access_token)
+    token && AccessToken.new(client, token, hash)
+  end
+
+private
+
+  def build_access_token(response, access_token_opts, extract_access_token)
+    parsed_response = response.parsed.dup
+    return unless parsed_response.is_a?(Hash)
+
+    hash = parsed_response.merge(access_token_opts)
+
+    # Provide backwards compatibility for old AcessToken.form_hash pattern
+    # Should be deprecated in 2.x
+    if extract_access_token.is_a?(Class) && extract_access_token.respond_to?(:from_hash)
+      extract_access_token.from_hash(self, hash) 
+    else
+      extract_access_token.call(self, hash)
+    end
+  end
 end
diff --git a/spec/oauth2/client_spec.rb b/spec/oauth2/client_spec.rb
index f045e044..2d3705d6 100644
--- a/spec/oauth2/client_spec.rb
+++ b/spec/oauth2/client_spec.rb
@@ -354,6 +354,122 @@
       client.get_token({})
     end
 
+    describe 'extract_access_token option' do
+      let(:client) do 
+        client = stubbed_client(:extract_access_token => extract_access_token) do |stub|
+          stub.post('/oauth/token') do
+            [200, {'Content-Type' => 'application/json'}, MultiJson.encode('data' => {'access_token' => 'the-token'})]
+          end
+        end
+      end
+
+      context "with proc extract_access_token" do
+        let(:extract_access_token) do
+          proc do |client, hash|
+            token = hash['data']['access_token']
+            AccessToken.new(client, token, hash)
+          end
+        end
+
+        it 'returns a configured AccessToken' do
+          token = client.get_token({})
+          expect(token).to be_a OAuth2::AccessToken
+          expect(token.token).to eq('the-token')
+        end
+      end
+
+      context "with depracted Class.from_hash option" do
+        let(:extract_access_token) do
+          CustomAccessToken = Class.new(AccessToken)
+          CustomAccessToken.define_singleton_method(:from_hash) do |client, hash| 
+            token = hash['data']['access_token']
+            AccessToken.new(client, token, hash)
+          end
+          CustomAccessToken
+        end
+
+        it 'returns a configured AccessToken' do
+          token = client.get_token({})
+          expect(token).to be_a OAuth2::AccessToken
+          expect(token.token).to eq('the-token')
+        end
+      end
+    end
+
+    describe ':raise_errors flag' do
+      let(:options) { {} }
+      let(:token_response) { nil }
+
+      let(:client) do
+        stubbed_client(options.merge(:raise_errors => raise_errors)) do |stub|
+          stub.post('/oauth/token') do
+            # stub 200 response so that we're testing the get_token handling of :raise_errors flag not request
+            [200, {'Content-Type' => 'application/json'}, token_response]
+          end
+        end
+      end
+
+      context 'when set to false' do
+        let(:raise_errors) { false }
+
+        context 'when the request body is nil' do
+          it 'returns a nil :access_token' do
+            expect(client.get_token({})).to eq(nil)
+          end
+        end
+
+        context 'when the request body is missing the access_token' do
+          let(:token_response) { MultiJson.encode('unexpected_access_token' => 'the-token') }
+
+          it 'returns a nil :access_token' do
+            expect(client.get_token({})).to eq(nil)
+          end
+        end
+
+        context 'when extract_access_token raises an exception' do
+          let(:options) do
+            {
+              :extract_access_token => proc { |client, hash| raise ArgumentError },
+            }
+          end
+
+          it 'returns a nil :access_token' do
+            expect(client.get_token({})).to eq(nil)
+          end
+        end
+      end
+
+      context 'when set to true' do
+        let(:raise_errors) { true }
+
+        context 'when the request body is nil' do
+          it 'raises an error' do
+            expect { client.get_token({}) }.to raise_error OAuth2::Error
+          end
+        end
+
+        context 'when the request body is missing the access_token' do
+          let(:token_response) { MultiJson.encode('unexpected_access_token' => 'the-token') }
+
+          it 'raises an error' do
+            expect { client.get_token({}) }.to raise_error OAuth2::Error
+          end
+        end
+
+        context 'when extract_access_token raises an exception' do
+          let(:options) do
+            {
+              :extract_access_token => proc { |client, hash| raise ArgumentError },
+            }
+          end
+
+          it 'raises an error' do
+            expect { client.get_token({}) }.to raise_error OAuth2::Error
+          end
+        end
+      end
+    end
+
     def stubbed_client(params = {}, &stubs)
       params = {:site => 'https://api.example.com'}.merge(params)
       OAuth2::Client.new('abc', 'def', params) do |builder|

From 94b1329545d842d796a15fb67001817973031340 Mon Sep 17 00:00:00 2001
From: Matt Boldt <me@mattboldt.com>
Date: Wed, 17 Mar 2021 19:00:53 -0500
Subject: [PATCH 031/163] Bump version to 1.4.5 to release #518 (#534)

* Remove deleted bin scripts from README

* Bump version to 1.4.5
---
 README.md             | 4 ++--
 lib/oauth2/version.rb | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/README.md b/README.md
index 55ea4d88..5a81ae3d 100644
--- a/README.md
+++ b/README.md
@@ -166,7 +166,7 @@ implementations:
 
 * Ruby 2.2 - Support ends with version 2.x series
 * Ruby 2.3 - Support ends with version 3.x series
-  - [JRuby 9.1][jruby-9.1] (targets MRI v2.3) 
+  - [JRuby 9.1][jruby-9.1] (targets MRI v2.3)
 * Ruby 2.4 - Support ends with version 4.x series
 * Ruby 2.5 - Support ends with version 5.x series
   - [JRuby 9.2][jruby-9.2] (targets MRI v2.5)
@@ -230,7 +230,7 @@ spec.add_dependency 'oauth2', '~> 1.4'
 
 ## Development
 
-After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
+After checking out the repo, run `bundle install` to install dependencies. Then, run `rake spec` to run the tests.
 
 To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
 
diff --git a/lib/oauth2/version.rb b/lib/oauth2/version.rb
index 684cdcfc..cc1365f4 100644
--- a/lib/oauth2/version.rb
+++ b/lib/oauth2/version.rb
@@ -20,7 +20,7 @@ def minor
     #
     # @return [Integer]
     def patch
-      4
+      5
     end
 
     # The pre-release version, if any

From 24fcfcfc9572adeb05aaa0dd95c9e967efe044f7 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Fri, 19 Mar 2021 03:37:33 +0700
Subject: [PATCH 032/163] Switch to Github Actions for Ruby 2.4|5|6|7 & 3
 (#535)

* Switch to Github Actions for Ruby 2.4|5|6|7 & 3.0

* Compatibility with latest Ruby OpenSSL

* Reduce Travis footprint
---
 .github/dependabot.yml                 |   8 ++
 .github/workflows/style.yml            |  37 ++++++++
 .github/workflows/test.yml             |  58 ++++++++++++
 .rubocop.yml                           |  50 +++++++++--
 .rubocop_todo.yml                      | 118 ++++++++++++++++++++++---
 .travis.yml                            |  16 +---
 CHANGELOG.md                           |   4 +-
 Gemfile                                |  49 +++++++---
 README.md                              |   2 +-
 Rakefile                               |   2 +-
 gemfiles/jruby_1.7.gemfile             |   2 +-
 gemfiles/jruby_9.0.gemfile             |   2 +-
 gemfiles/ruby_1.9.gemfile              |   2 +-
 gemfiles/ruby_2.1.gemfile              |   6 --
 gemfiles/ruby_2.2.gemfile              |   3 -
 gemfiles/ruby_2.3.gemfile              |   3 -
 gemfiles/ruby_2.4.gemfile              |   3 -
 gemfiles/ruby_2.5.gemfile              |   3 -
 gemfiles/ruby_2.6.gemfile              |   9 --
 gemfiles/ruby_2.7.gemfile              |   9 --
 gemfiles/ruby_head.gemfile             |   2 +-
 lib/oauth2/access_token.rb             |   8 +-
 lib/oauth2/authenticator.rb            |   2 +-
 lib/oauth2/client.rb                   |  34 ++++---
 lib/oauth2/mac_token.rb                |  12 ++-
 lib/oauth2/response.rb                 |   8 +-
 lib/oauth2/strategy/assertion.rb       |   6 +-
 lib/oauth2/strategy/password.rb        |   4 +-
 maintenance-branch                     |   1 +
 oauth2.gemspec                         |  12 +--
 spec/helper.rb                         |   8 +-
 spec/oauth2/access_token_spec.rb       |   4 +-
 spec/oauth2/client_spec.rb             |  28 +++---
 spec/oauth2/response_spec.rb           |   4 +-
 spec/oauth2/strategy/assertion_spec.rb |   4 +-
 35 files changed, 376 insertions(+), 147 deletions(-)
 create mode 100644 .github/dependabot.yml
 create mode 100644 .github/workflows/style.yml
 create mode 100644 .github/workflows/test.yml
 delete mode 100644 gemfiles/ruby_2.1.gemfile
 delete mode 100644 gemfiles/ruby_2.2.gemfile
 delete mode 100644 gemfiles/ruby_2.3.gemfile
 delete mode 100644 gemfiles/ruby_2.4.gemfile
 delete mode 100644 gemfiles/ruby_2.5.gemfile
 delete mode 100644 gemfiles/ruby_2.6.gemfile
 delete mode 100644 gemfiles/ruby_2.7.gemfile
 create mode 100644 maintenance-branch

diff --git a/.github/dependabot.yml b/.github/dependabot.yml
new file mode 100644
index 00000000..a0267668
--- /dev/null
+++ b/.github/dependabot.yml
@@ -0,0 +1,8 @@
+version: 2
+updates:
+  - package-ecosystem: bundler
+    directory: "/"
+    schedule:
+      interval: daily
+      time: "04:28"
+    open-pull-requests-limit: 10
\ No newline at end of file
diff --git a/.github/workflows/style.yml b/.github/workflows/style.yml
new file mode 100644
index 00000000..fd211ace
--- /dev/null
+++ b/.github/workflows/style.yml
@@ -0,0 +1,37 @@
+name: Code Style Checks
+
+on:
+  push:
+    branches:
+      - 'main'
+      - 'master'
+      - '*-maintenance'
+      - '*-dev'
+    tags:
+      - '!*' # Do not execute on tags
+  pull_request:
+    branches:
+      - '*'
+
+jobs:
+  rubocop:
+    name: Rubocop
+    if: "!contains(github.event.commits[0].message, '[ci skip]') && !contains(github.event.commits[0].message, '[skip ci]')"
+    strategy:
+      fail-fast: false
+      matrix:
+        ruby:
+          - 2.7
+    runs-on: ubuntu-20.04
+    steps:
+      - name: Checkout
+        uses: actions/checkout@v2
+      - name: Setup Ruby
+        uses: ruby/setup-ruby@v1
+        with:
+          ruby-version: ${{ matrix.ruby }}
+          bundler-cache: true
+      - name: Install dependencies
+        run: bundle install --jobs 3 --retry 3
+      - name: Run Rubocop
+        run: bundle exec rubocop -DESP
\ No newline at end of file
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
new file mode 100644
index 00000000..9d0352ab
--- /dev/null
+++ b/.github/workflows/test.yml
@@ -0,0 +1,58 @@
+name: Unit Tests
+
+on:
+  push:
+    branches:
+      - 'main'
+      - 'master'
+      - '*-maintenance'
+      - '*-dev'
+    tags:
+      - '!*' # Do not execute on tags
+  pull_request:
+    branches:
+      - '*'
+
+jobs:
+  test:
+    name: Specs - Ruby ${{ matrix.ruby }} ${{ matrix.name_extra || '' }}
+    if: "!contains(github.event.commits[0].message, '[ci skip]') && !contains(github.event.commits[0].message, '[skip ci]')"
+    strategy:
+      fail-fast: false
+      matrix:
+        ruby:
+          - 3.0.0
+          - 2.7
+          - 2.6
+          - 2.5
+          - 2.4
+          - 2.3
+          - 2.2
+          - 2.1
+    runs-on: ubuntu-20.04
+    continue-on-error: ${{ matrix.allow_failure || endsWith(matrix.ruby, 'head') }}
+    steps:
+      - uses: amancevice/setup-code-climate@v0
+        name: CodeClimate Install
+        if: matrix.ruby == '2.7' && github.event_name != 'pull_request'
+        with:
+          cc_test_reporter_id: ${{ secrets.CC_TEST_REPORTER_ID }}
+      - uses: actions/checkout@v2
+      - name: Setup Ruby
+        uses: ruby/setup-ruby@v1
+        with:
+          bundler: ${{ matrix.bundler || 2 }}
+          bundler-cache: true
+          ruby-version: ${{ matrix.ruby }}
+      - name: Install dependencies
+        run: bundle install --jobs 3 --retry 3 --binstubs --standalone
+      - name: CodeClimate Pre-build Notification
+        run: cc-test-reporter before-build
+        if: matrix.ruby == '2.7' && github.event_name != 'pull_request'
+        continue-on-error: ${{ matrix.allow_failures != 'false' }}
+      - name: Run tests
+        run: bundle exec rake test
+      - name: CodeClimate Post-build Notification
+        run: cc-test-reporter after-build
+        if: matrix.ruby == '2.7' && github.event_name != 'pull_request' && always()
+        continue-on-error: ${{ matrix.allow_failures != 'false' }}
diff --git a/.rubocop.yml b/.rubocop.yml
index c6a41973..3c1afd65 100644
--- a/.rubocop.yml
+++ b/.rubocop.yml
@@ -1,30 +1,42 @@
-require: rubocop-rspec
 inherit_from:
   - .rubocop_todo.yml
   - .rubocop_rspec.yml
+
+require:
+  - 'rubocop-md'
+  - 'rubocop-packaging'
+  - 'rubocop-performance'
+  - 'rubocop-rake'
+  - 'rubocop-rspec'
+
 AllCops:
+  NewCops: enable
   DisplayCopNames: true # Display the name of the failing cops
-  TargetRubyVersion: 2.1
   Exclude:
     - 'gemfiles/vendor/**/*'
     - 'vendor/**/*'
     - '**/.irbrc'
 
-Gemspec/RequiredRubyVersion:
-  Enabled: false
-
 Metrics/BlockLength:
+  IgnoredMethods:
+    - context
+    - describe
+    - it
+    - shared_context
+    - shared_examples
+    - shared_examples_for
+    - namespace
+    - draw
+
+Gemspec/RequiredRubyVersion:
   Enabled: false
 
 Metrics/BlockNesting:
   Max: 2
 
-Metrics/LineLength:
+Layout/LineLength:
   Enabled: false
 
-Metrics/MethodLength:
-  Max: 15
-
 Metrics/ParameterLists:
   Max: 4
 
@@ -78,3 +90,23 @@ Style/TrailingCommaInArrayLiteral:
 
 Style/TrailingCommaInHashLiteral:
   EnforcedStyleForMultiline: comma
+
+Style/HashSyntax:
+  EnforcedStyle: hash_rockets
+
+Style/Lambda:
+  Enabled: false
+
+Style/SymbolArray:
+  Enabled: false
+
+Style/EachWithObject:
+  Enabled: false
+
+# Once we drop Rubies that lack support for __dir__ we can turn this on.
+Style/ExpandPathArguments:
+  Enabled: false
+
+# On Ruby 1.9 array.to_h isn't available, needs to be Hash[array]
+Style/HashConversion:
+  Enabled: false
\ No newline at end of file
diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml
index e7701734..f430c2d1 100644
--- a/.rubocop_todo.yml
+++ b/.rubocop_todo.yml
@@ -1,15 +1,113 @@
-Style/HashSyntax:
-  EnforcedStyle: hash_rockets
+# This configuration was generated by
+# `rubocop --auto-gen-config`
+# on 2021-03-18 18:59:52 UTC using RuboCop version 1.11.0.
+# The point is for the user to remove these configuration records
+# one by one as the offenses are removed from the code base.
+# Note that changes in the inspected code, or installation of new
+# versions of RuboCop, may require this file to be generated again.
 
-Style/Lambda:
-  Enabled: false
+# Offense count: 1
+# Configuration parameters: AllowedMethods.
+# AllowedMethods: enums
+Lint/ConstantDefinitionInBlock:
+  Exclude:
+    - 'spec/oauth2/client_spec.rb'
 
-Style/SymbolArray:
-  Enabled: false
+# Offense count: 1
+Lint/UselessAssignment:
+  Exclude:
+    - '**/*.md'
+    - '**/*.markdown'
+    - 'spec/oauth2/client_spec.rb'
 
-Style/EachWithObject:
-  Enabled: false
+# Offense count: 1
+# Configuration parameters: CountComments, CountAsOne, ExcludedMethods, IgnoredMethods.
+# IgnoredMethods: refine
+Metrics/BlockLength:
+  Max: 27
+
+# Offense count: 4
+# Configuration parameters: IgnoredMethods.
+Metrics/CyclomaticComplexity:
+  Max: 11
+
+# Offense count: 1
+# Configuration parameters: CountComments, CountAsOne, ExcludedMethods, IgnoredMethods.
+Metrics/MethodLength:
+  Max: 18
+
+# Offense count: 3
+# Configuration parameters: IgnoredMethods.
+Metrics/PerceivedComplexity:
+  Max: 11
+
+# Offense count: 14
+# Configuration parameters: EnforcedStyle, CheckMethodNames, CheckSymbols, AllowedIdentifiers.
+# SupportedStyles: snake_case, normalcase, non_integer
+# AllowedIdentifiers: capture3, iso8601, rfc1123_date, rfc822, rfc2822, rfc3339
+Naming/VariableNumber:
+  Exclude:
+    - 'Gemfile'
+
+# Offense count: 1
+Packaging/GemspecGit:
+  Exclude:
+    - 'oauth2.gemspec'
 
-# Once we drop Rubies that lack support for __dir__ we can turn this on.
-Style/ExpandPathArguments:
+# Offense count: 2
+# Configuration parameters: MinSize.
+Performance/CollectionLiteralInLoop:
+  Exclude:
+    - 'spec/oauth2/strategy/auth_code_spec.rb'
+    - 'spec/oauth2/strategy/client_credentials_spec.rb'
+
+# Offense count: 7
+# Configuration parameters: Prefixes.
+# Prefixes: when, with, without
+RSpec/ContextWording:
+  Exclude:
+    - 'spec/oauth2/access_token_spec.rb'
+    - 'spec/oauth2/authenticator_spec.rb'
+    - 'spec/oauth2/client_spec.rb'
+
+# Offense count: 1
+RSpec/LeakyConstantDeclaration:
+  Exclude:
+    - 'spec/oauth2/client_spec.rb'
+
+# Offense count: 8
+# Configuration parameters: AllowSubject.
+RSpec/MultipleMemoizedHelpers:
+  Max: 6
+
+# Offense count: 1
+Rake/Desc:
+  Exclude:
+    - 'Rakefile'
+
+# Offense count: 40
+# Cop supports --auto-correct.
+# Configuration parameters: EnforcedStyle.
+# SupportedStyles: always, always_true, never
+Style/FrozenStringLiteralComment:
   Enabled: false
+
+# Offense count: 1
+Style/MixinUsage:
+  Exclude:
+    - 'spec/helper.rb'
+
+# Offense count: 1
+# Cop supports --auto-correct.
+# Configuration parameters: ConvertCodeThatCanStartToReturnNil, AllowedMethods.
+# AllowedMethods: present?, blank?, presence, try, try!
+Style/SafeNavigation:
+  Exclude:
+    - 'lib/oauth2/error.rb'
+
+# Offense count: 3
+# Cop supports --auto-correct.
+Style/StringConcatenation:
+  Exclude:
+    - 'lib/oauth2/authenticator.rb'
+    - 'spec/oauth2/authenticator_spec.rb'
diff --git a/.travis.yml b/.travis.yml
index 6c65fe29..26059437 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -56,27 +56,15 @@ matrix:
       gemfile: gemfiles/ruby_2.0.gemfile
     - rvm: jruby-9.0 # targets MRI v2.0
       gemfile: gemfiles/jruby_9.0.gemfile
-    - rvm: 2.1
-      gemfile: gemfiles/ruby_2.1.gemfile
     # DEPRECATION WARNING
+    # NOTE: Specs for Ruby 2.1 are now running with Github Actions
     # oauth2 1.x series releases are the last to support Ruby versions above
     # oauth2 2.x series releases will support Ruby versions below, and not above
+    # NOTE: Specs for Ruby 2.2, 2.3, 2.4, 2.5, 2.6, 2.7 & 3.0 are now running with Github Actions
     - rvm: jruby-9.1 # targets MRI v2.3
       gemfile: gemfiles/jruby_9.1.gemfile
-    - rvm: 2.2
-      gemfile: gemfiles/ruby_2.2.gemfile
-    - rvm: 2.3
-      gemfile: gemfiles/ruby_2.3.gemfile
-    - rvm: 2.4
-      gemfile: gemfiles/ruby_2.4.gemfile
     - rvm: jruby-9.2 # targets MRI v2.5
       gemfile: gemfiles/jruby_9.2.gemfile
-    - rvm: 2.5
-      gemfile: gemfiles/ruby_2.5.gemfile
-    - rvm: 2.6
-      gemfile: gemfiles/ruby_2.6.gemfile
-    - rvm: 2.7
-      gemfile: gemfiles/ruby_2.7.gemfile
     - rvm: jruby-head
       gemfile: gemfiles/jruby_head.gemfile
     - rvm: ruby-head
diff --git a/CHANGELOG.md b/CHANGELOG.md
index e8303128..e1e04a6a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,9 +1,9 @@
 # Change Log
 All notable changes to this project will be documented in this file.
 
-## [unreleased]
+## unreleased
 
-- no changes yet
+- [#518](https://github.com/oauth-xx/oauth2/pull/518) - Add extract_access_token option to OAuth2::Client (@jonspalmer)
 
 ## [1.4.4] - 2020-02-12
 
diff --git a/Gemfile b/Gemfile
index 0dbce159..4657b438 100644
--- a/Gemfile
+++ b/Gemfile
@@ -1,29 +1,52 @@
+# frozen_string_literal: true
+
 source 'https://rubygems.org'
 
+gemspec
+
 git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
 
 gem 'faraday', ['>= 0.8', '< 2.0'], :platforms => [:jruby_18, :ruby_18]
 gem 'jwt', '< 1.5.2', :platforms => [:jruby_18, :ruby_18]
 gem 'rake', '< 11.0'
-gem 'rdoc', '~> 4.2.2'
 
-group :test do
-  ruby_version = Gem::Version.new(RUBY_VERSION)
-  if ruby_version >= Gem::Version.new('2.1')
-    # TODO: Upgrade to >= 0.59 when we drop Rubies below 2.2
-    #     Error: Unsupported Ruby version 2.1 found in `TargetRubyVersion` parameter (in .rubocop.yml). 2.1-compatible analysis was dropped after version 0.58.
-    #     Supported versions: 2.2, 2.3, 2.4, 2.5
-    gem 'rubocop', '~> 0.57.0'
-    gem 'rubocop-rspec', '~> 1.27.0' # last version that can use rubocop < 0.58
+ruby_version = Gem::Version.new(RUBY_VERSION)
+
+### deps for documentation and rdoc.info
+group :documentation do
+  gem 'github-markup', :platform => :mri
+  gem 'rdoc'
+  gem 'redcarpet', :platform => :mri
+  gem 'yard', :require => false
+end
+
+group :development, :test do
+  if ruby_version >= Gem::Version.new('2.4')
+    # No need to run byebug / pry on earlier versions
+    gem 'byebug', :platform => :mri
+    gem 'pry', :platform => :mri
+    gem 'pry-byebug', :platform => :mri
   end
-  gem 'pry', '~> 0.11' if ruby_version >= Gem::Version.new('2.0')
 
+  if ruby_version >= Gem::Version.new('2.7')
+    # No need to run rubocop or simplecov on earlier versions
+    gem 'rubocop', '~> 1.9', :platform => :mri
+    gem 'rubocop-md', :platform => :mri
+    gem 'rubocop-packaging', :platform => :mri
+    gem 'rubocop-performance', :platform => :mri
+    gem 'rubocop-rake', :platform => :mri
+    gem 'rubocop-rspec', :platform => :mri
+
+    gem 'coveralls'
+    gem 'simplecov', :platform => :mri
+  end
+end
+
+group :test do
   gem 'addressable', '~> 2.3.8'
   gem 'backports'
-  gem 'coveralls'
   gem 'rack', '~> 1.2', :platforms => [:jruby_18, :jruby_19, :ruby_18, :ruby_19, :ruby_20, :ruby_21]
   gem 'rspec', '>= 3'
-  gem 'simplecov', '>= 0.9'
 
   platforms :jruby_18, :ruby_18 do
     gem 'mime-types', '~> 1.25'
@@ -36,5 +59,3 @@ group :test do
     gem 'tins', '< 1.7'
   end
 end
-
-gemspec
diff --git a/README.md b/README.md
index 5a81ae3d..8cff087e 100644
--- a/README.md
+++ b/README.md
@@ -79,7 +79,7 @@ client.auth_code.authorize_url(:redirect_uri => 'http://localhost:8080/oauth2/ca
 # => "https://example.org/oauth/authorization?response_type=code&client_id=client_id&redirect_uri=http://localhost:8080/oauth2/callback"
 
 token = client.auth_code.get_token('authorization_code_value', :redirect_uri => 'http://localhost:8080/oauth2/callback', :headers => {'Authorization' => 'Basic some_password'})
-response = token.get('/api/resource', :params => { 'query_foo' => 'bar' })
+response = token.get('/api/resource', :params => {'query_foo' => 'bar'})
 response.class.name
 # => OAuth2::Response
 ```
diff --git a/Rakefile b/Rakefile
index 1066a1b6..19bdfa31 100644
--- a/Rakefile
+++ b/Rakefile
@@ -33,7 +33,7 @@ end
 
 namespace :doc do
   require 'rdoc/task'
-  require File.expand_path('../lib/oauth2/version', __FILE__)
+  require 'oauth2/version'
   RDoc::Task.new do |rdoc|
     rdoc.rdoc_dir = 'rdoc'
     rdoc.title = "oauth2 #{OAuth2::Version}"
diff --git a/gemfiles/jruby_1.7.gemfile b/gemfiles/jruby_1.7.gemfile
index bbef7523..276621ef 100644
--- a/gemfiles/jruby_1.7.gemfile
+++ b/gemfiles/jruby_1.7.gemfile
@@ -4,7 +4,7 @@ gem 'faraday', '~> 0.15.4'
 
 gem 'json', '< 2.0'
 gem 'rack', '~> 1.2'
-gem 'rake', [">= 10.0", "< 12"]
+gem 'rake', ['>= 10.0', '< 12']
 gem 'term-ansicolor', '< 1.4.0'
 gem 'tins', '< 1.7'
 
diff --git a/gemfiles/jruby_9.0.gemfile b/gemfiles/jruby_9.0.gemfile
index 13fd08d3..6d3ebd53 100644
--- a/gemfiles/jruby_9.0.gemfile
+++ b/gemfiles/jruby_9.0.gemfile
@@ -2,6 +2,6 @@ source 'https://rubygems.org'
 
 gem 'faraday', '~> 0.15.4'
 
-gem 'rake', [">= 10.0", "< 12"]
+gem 'rake', ['>= 10.0', '< 12']
 
 gemspec :path => '../'
diff --git a/gemfiles/ruby_1.9.gemfile b/gemfiles/ruby_1.9.gemfile
index bbef7523..276621ef 100644
--- a/gemfiles/ruby_1.9.gemfile
+++ b/gemfiles/ruby_1.9.gemfile
@@ -4,7 +4,7 @@ gem 'faraday', '~> 0.15.4'
 
 gem 'json', '< 2.0'
 gem 'rack', '~> 1.2'
-gem 'rake', [">= 10.0", "< 12"]
+gem 'rake', ['>= 10.0', '< 12']
 gem 'term-ansicolor', '< 1.4.0'
 gem 'tins', '< 1.7'
 
diff --git a/gemfiles/ruby_2.1.gemfile b/gemfiles/ruby_2.1.gemfile
deleted file mode 100644
index 87a679f6..00000000
--- a/gemfiles/ruby_2.1.gemfile
+++ /dev/null
@@ -1,6 +0,0 @@
-source 'https://rubygems.org'
-
-gem 'faraday', '~> 0.15.4'
-gem 'rack', '~> 1.2'
-
-gemspec :path => '../'
diff --git a/gemfiles/ruby_2.2.gemfile b/gemfiles/ruby_2.2.gemfile
deleted file mode 100644
index a02c547f..00000000
--- a/gemfiles/ruby_2.2.gemfile
+++ /dev/null
@@ -1,3 +0,0 @@
-source 'https://rubygems.org'
-
-gemspec :path => '../'
diff --git a/gemfiles/ruby_2.3.gemfile b/gemfiles/ruby_2.3.gemfile
deleted file mode 100644
index a02c547f..00000000
--- a/gemfiles/ruby_2.3.gemfile
+++ /dev/null
@@ -1,3 +0,0 @@
-source 'https://rubygems.org'
-
-gemspec :path => '../'
diff --git a/gemfiles/ruby_2.4.gemfile b/gemfiles/ruby_2.4.gemfile
deleted file mode 100644
index a02c547f..00000000
--- a/gemfiles/ruby_2.4.gemfile
+++ /dev/null
@@ -1,3 +0,0 @@
-source 'https://rubygems.org'
-
-gemspec :path => '../'
diff --git a/gemfiles/ruby_2.5.gemfile b/gemfiles/ruby_2.5.gemfile
deleted file mode 100644
index a02c547f..00000000
--- a/gemfiles/ruby_2.5.gemfile
+++ /dev/null
@@ -1,3 +0,0 @@
-source 'https://rubygems.org'
-
-gemspec :path => '../'
diff --git a/gemfiles/ruby_2.6.gemfile b/gemfiles/ruby_2.6.gemfile
deleted file mode 100644
index 822e2f2c..00000000
--- a/gemfiles/ruby_2.6.gemfile
+++ /dev/null
@@ -1,9 +0,0 @@
-source 'https://rubygems.org'
-
-group :development do
-  gem 'pry'
-  gem 'byebug'
-  gem 'pry-byebug'
-end
-
-gemspec :path => '../'
diff --git a/gemfiles/ruby_2.7.gemfile b/gemfiles/ruby_2.7.gemfile
deleted file mode 100644
index 822e2f2c..00000000
--- a/gemfiles/ruby_2.7.gemfile
+++ /dev/null
@@ -1,9 +0,0 @@
-source 'https://rubygems.org'
-
-group :development do
-  gem 'pry'
-  gem 'byebug'
-  gem 'pry-byebug'
-end
-
-gemspec :path => '../'
diff --git a/gemfiles/ruby_head.gemfile b/gemfiles/ruby_head.gemfile
index 822e2f2c..c7a3bfd9 100644
--- a/gemfiles/ruby_head.gemfile
+++ b/gemfiles/ruby_head.gemfile
@@ -1,8 +1,8 @@
 source 'https://rubygems.org'
 
 group :development do
-  gem 'pry'
   gem 'byebug'
+  gem 'pry'
   gem 'pry-byebug'
 end
 
diff --git a/lib/oauth2/access_token.rb b/lib/oauth2/access_token.rb
index 656eccba..db8c2239 100644
--- a/lib/oauth2/access_token.rb
+++ b/lib/oauth2/access_token.rb
@@ -49,9 +49,9 @@ def initialize(client, token, opts = {}) # rubocop:disable Metrics/AbcSize
       @expires_in &&= @expires_in.to_i
       @expires_at &&= convert_expires_at(@expires_at)
       @expires_at ||= Time.now.to_i + @expires_in if @expires_in
-      @options = {:mode          => opts.delete(:mode) || :header,
+      @options = {:mode => opts.delete(:mode) || :header,
                   :header_format => opts.delete(:header_format) || 'Bearer %s',
-                  :param_name    => opts.delete(:param_name) || 'access_token'}
+                  :param_name => opts.delete(:param_name) || 'access_token'}
       @params = opts
     end
 
@@ -82,6 +82,7 @@ def expired?
     # @note options should be carried over to the new AccessToken
     def refresh!(params = {})
       raise('A refresh_token is not available') unless refresh_token
+
       params[:grant_type] = 'refresh_token'
       params[:refresh_token] = refresh_token
       new_token = @client.get_token(params)
@@ -150,7 +151,7 @@ def headers
 
   private
 
-    def configure_authentication!(opts) # rubocop:disable MethodLength, Metrics/AbcSize
+    def configure_authentication!(opts) # rubocop:disable Metrics/AbcSize
       case options[:mode]
       when :header
         opts[:headers] ||= {}
@@ -175,6 +176,7 @@ def convert_expires_at(expires_at)
       expires_at_i = expires_at.to_i
       return expires_at_i if expires_at_i > Time.now.utc.to_i
       return Time.parse(expires_at).to_i if expires_at.is_a?(String)
+
       expires_at_i
     end
   end
diff --git a/lib/oauth2/authenticator.rb b/lib/oauth2/authenticator.rb
index 6194b837..9588da34 100644
--- a/lib/oauth2/authenticator.rb
+++ b/lib/oauth2/authenticator.rb
@@ -49,7 +49,7 @@ def apply_params_auth(params)
     # When using schemes that don't require the client_secret to be passed i.e TLS Client Auth,
     # we don't want to send the secret
     def apply_client_id(params)
-      { 'client_id' => id }.merge(params)
+      {'client_id' => id}.merge(params)
     end
 
     # Adds an `Authorization` header with Basic Auth credentials if and only if
diff --git a/lib/oauth2/client.rb b/lib/oauth2/client.rb
index eb354a45..1cba2402 100644
--- a/lib/oauth2/client.rb
+++ b/lib/oauth2/client.rb
@@ -36,16 +36,16 @@ def initialize(client_id, client_secret, options = {}, &block)
       ssl = opts.delete(:ssl)
 
       @options = {
-        :authorize_url        => '/oauth/authorize',
-        :token_url            => '/oauth/token',
-        :token_method         => :post,
-        :auth_scheme          => :request_body,
-        :connection_opts      => {},
-        :connection_build     => block,
-        :max_redirects        => 5,
-        :raise_errors         => true,
-        :extract_access_token => DEFAULT_EXTRACT_ACCESS_TOKEN
-                }.merge(opts)
+        :authorize_url => '/oauth/authorize',
+        :token_url => '/oauth/token',
+        :token_method => :post,
+        :auth_scheme => :request_body,
+        :connection_opts => {},
+        :connection_build => block,
+        :max_redirects => 5,
+        :raise_errors => true,
+        :extract_access_token => DEFAULT_EXTRACT_ACCESS_TOKEN,
+      }.merge(opts)
       @options[:connection_opts][:ssl] = ssl if ssl
     end
 
@@ -97,7 +97,7 @@ def token_url(params = nil)
     #   code response for this request.  Will default to client option
     # @option opts [Symbol] :parse @see Response::initialize
     # @yield [req] The Faraday request
-    def request(verb, url, opts = {}) # rubocop:disable CyclomaticComplexity, MethodLength, Metrics/AbcSize, Metrics/PerceivedComplexity
+    def request(verb, url, opts = {}) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
       connection.response :logger, ::Logger.new($stdout) if ENV['OAUTH_DEBUG'] == 'true'
 
       url = connection.build_url(url).to_s
@@ -113,6 +113,7 @@ def request(verb, url, opts = {}) # rubocop:disable CyclomaticComplexity, Method
         opts[:redirect_count] ||= 0
         opts[:redirect_count] += 1
         return response if opts[:redirect_count] > options[:max_redirects]
+
         if response.status == 303
           verb = :get
           opts.delete(:body)
@@ -124,6 +125,7 @@ def request(verb, url, opts = {}) # rubocop:disable CyclomaticComplexity, Method
       when 400..599
         error = Error.new(response)
         raise(error) if opts.fetch(:raise_errors, options[:raise_errors])
+
         response.error = error
         response
       else
@@ -138,7 +140,7 @@ def request(verb, url, opts = {}) # rubocop:disable CyclomaticComplexity, Method
     # @param [Hash] access token options, to pass to the AccessToken object
     # @param [Class] class of access token for easier subclassing OAuth2::AccessToken
     # @return [AccessToken] the initialized AccessToken
-    def get_token(params, access_token_opts = {}, extract_access_token = options[:extract_access_token]) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/PerceivedComplexity
+    def get_token(params, access_token_opts = {}, extract_access_token = options[:extract_access_token]) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
       params = params.map do |key, value|
         if RESERVED_PARAM_KEYS.include?(key)
           [key.to_sym, value]
@@ -161,7 +163,11 @@ def get_token(params, access_token_opts = {}, extract_access_token = options[:ex
       opts[:headers].merge!(headers)
       response = request(options[:token_method], token_url, opts)
 
-      access_token = build_access_token(response, access_token_opts, extract_access_token) rescue nil
+      access_token = begin
+        build_access_token(response, access_token_opts, extract_access_token)
+      rescue StandardError
+        nil
+      end
 
       if options[:raise_errors] && !access_token
         error = Error.new(response)
@@ -243,7 +249,7 @@ def build_access_token(response, access_token_opts, extract_access_token)
     # Provide backwards compatibility for old AcessToken.form_hash pattern
     # Should be deprecated in 2.x
     if extract_access_token.is_a?(Class) && extract_access_token.respond_to?(:from_hash)
-      extract_access_token.from_hash(self, hash) 
+      extract_access_token.from_hash(self, hash)
     else
       extract_access_token.call(self, hash)
     end
diff --git a/lib/oauth2/mac_token.rb b/lib/oauth2/mac_token.rb
index db7d4d77..99c6f5ec 100644
--- a/lib/oauth2/mac_token.rb
+++ b/lib/oauth2/mac_token.rb
@@ -98,9 +98,17 @@ def algorithm=(alg)
       @algorithm = begin
         case alg.to_s
         when 'hmac-sha-1'
-          OpenSSL::Digest::SHA1.new
+          begin
+            OpenSSL::Digest('SHA1').new
+          rescue StandardError
+            OpenSSL::Digest.new('SHA1')
+          end
         when 'hmac-sha-256'
-          OpenSSL::Digest::SHA256.new
+          begin
+            OpenSSL::Digest('SHA256').new
+          rescue StandardError
+            OpenSSL::Digest.new('SHA256')
+          end
         else
           raise(ArgumentError, 'Unsupported algorithm')
         end
diff --git a/lib/oauth2/response.rb b/lib/oauth2/response.rb
index 13657fd9..fd98617b 100644
--- a/lib/oauth2/response.rb
+++ b/lib/oauth2/response.rb
@@ -11,9 +11,9 @@ class Response
     # Procs that, when called, will parse a response body according
     # to the specified format.
     @@parsers = {
-      :json  => lambda { |body| MultiJson.load(body) rescue body }, # rubocop:disable RescueModifier
+      :json => lambda { |body| MultiJson.load(body) rescue body }, # rubocop:disable Style/RescueModifier
       :query => lambda { |body| Rack::Utils.parse_query(body) },
-      :text  => lambda { |body| body },
+      :text => lambda { |body| body },
     }
 
     # Content type assignments for various potential HTTP content types.
@@ -68,6 +68,7 @@ def body
     #   application/json Content-Type response bodies
     def parsed
       return nil unless @@parsers.key?(parser)
+
       @parsed ||= @@parsers[parser].call(body)
     end
 
@@ -79,11 +80,12 @@ def content_type
     # Determines the parser that will be used to supply the content of #parsed
     def parser
       return options[:parse].to_sym if @@parsers.key?(options[:parse])
+
       @@content_types[content_type]
     end
   end
 end
 
 OAuth2::Response.register_parser(:xml, ['text/xml', 'application/rss+xml', 'application/rdf+xml', 'application/atom+xml']) do |body|
-  MultiXml.parse(body) rescue body # rubocop:disable RescueModifier
+  MultiXml.parse(body) rescue body # rubocop:disable Style/RescueModifier
 end
diff --git a/lib/oauth2/strategy/assertion.rb b/lib/oauth2/strategy/assertion.rb
index b3b577be..8dc27b50 100644
--- a/lib/oauth2/strategy/assertion.rb
+++ b/lib/oauth2/strategy/assertion.rb
@@ -50,10 +50,10 @@ def get_token(params = {}, opts = {})
       def build_request(params)
         assertion = build_assertion(params)
         {
-          :grant_type     => 'assertion',
+          :grant_type => 'assertion',
           :assertion_type => 'urn:ietf:params:oauth:grant-type:jwt-bearer',
-          :assertion      => assertion,
-          :scope          => params[:scope],
+          :assertion => assertion,
+          :scope => params[:scope],
         }
       end
 
diff --git a/lib/oauth2/strategy/password.rb b/lib/oauth2/strategy/password.rb
index 49bfc6e3..075dec51 100644
--- a/lib/oauth2/strategy/password.rb
+++ b/lib/oauth2/strategy/password.rb
@@ -18,8 +18,8 @@ def authorize_url
       # @param [Hash] params additional params
       def get_token(username, password, params = {}, opts = {})
         params = {'grant_type' => 'password',
-                  'username'   => username,
-                  'password'   => password}.merge(params)
+                  'username' => username,
+                  'password' => password}.merge(params)
         @client.get_token(params, opts)
       end
     end
diff --git a/maintenance-branch b/maintenance-branch
new file mode 100644
index 00000000..8b25206f
--- /dev/null
+++ b/maintenance-branch
@@ -0,0 +1 @@
+master
\ No newline at end of file
diff --git a/oauth2.gemspec b/oauth2.gemspec
index 1e8b8aa1..9c58103b 100644
--- a/oauth2.gemspec
+++ b/oauth2.gemspec
@@ -23,11 +23,11 @@ Gem::Specification.new do |spec|
   spec.version       = OAuth2::Version
 
   spec.metadata = {
-    'bug_tracker_uri'   => 'https://github.com/oauth-xx/oauth2/issues',
-    'changelog_uri'     => "https://github.com/oauth-xx/oauth2/blob/v#{spec.version}/CHANGELOG.md",
+    'bug_tracker_uri' => 'https://github.com/oauth-xx/oauth2/issues',
+    'changelog_uri' => "https://github.com/oauth-xx/oauth2/blob/v#{spec.version}/CHANGELOG.md",
     'documentation_uri' => "https://www.rubydoc.info/gems/oauth2/#{spec.version}",
-    'source_code_uri'   => "https://github.com/oauth-xx/oauth2/tree/v#{spec.version}",
-    'wiki_uri'          => 'https://github.com/oauth-xx/oauth2/wiki'
+    'source_code_uri' => "https://github.com/oauth-xx/oauth2/tree/v#{spec.version}",
+    'wiki_uri' => 'https://github.com/oauth-xx/oauth2/wiki',
   }
 
   spec.require_paths = %w[lib]
@@ -44,9 +44,9 @@ Gem::Specification.new do |spec|
   spec.add_development_dependency 'rake', '~> 12.3'
   spec.add_development_dependency 'rdoc', ['>= 5.0', '< 7']
   spec.add_development_dependency 'rspec', '~> 3.0'
-  spec.add_development_dependency 'rspec-stubbed_env'
-  spec.add_development_dependency 'rspec-pending_for'
   spec.add_development_dependency 'rspec-block_is_expected'
+  spec.add_development_dependency 'rspec-pending_for'
+  spec.add_development_dependency 'rspec-stubbed_env'
   spec.add_development_dependency 'silent_stream'
   spec.add_development_dependency 'wwtd'
 end
diff --git a/spec/helper.rb b/spec/helper.rb
index e3cf4805..5ce4d82f 100644
--- a/spec/helper.rb
+++ b/spec/helper.rb
@@ -1,6 +1,8 @@
 DEBUG = ENV['DEBUG'] == 'true'
 
-if RUBY_VERSION >= '1.9'
+ruby_version = Gem::Version.new(RUBY_VERSION)
+
+if ruby_version >= Gem::Version.new('2.7')
   require 'simplecov'
   require 'coveralls'
 
@@ -12,9 +14,7 @@
   end
 end
 
-if DEBUG && RUBY_VERSION >= '2.6'
-  require 'byebug'
-end
+require 'byebug' if DEBUG && ruby_version >= Gem::Version.new('2.4')
 
 require 'oauth2'
 require 'addressable/uri'
diff --git a/spec/oauth2/access_token_spec.rb b/spec/oauth2/access_token_spec.rb
index cb3f45f3..93890491 100644
--- a/spec/oauth2/access_token_spec.rb
+++ b/spec/oauth2/access_token_spec.rb
@@ -167,8 +167,8 @@ def assert_initialized_token(target) # rubocop:disable Metrics/AbcSize
   describe '#refresh!' do
     let(:access) do
       described_class.new(client, token, :refresh_token => 'abaca',
-                                         :expires_in     => 600,
-                                         :param_name     => 'o_param')
+                                         :expires_in => 600,
+                                         :param_name => 'o_param')
     end
 
     it 'returns a refresh token with appropriate values carried over' do
diff --git a/spec/oauth2/client_spec.rb b/spec/oauth2/client_spec.rb
index 2d3705d6..46f75b4b 100644
--- a/spec/oauth2/client_spec.rb
+++ b/spec/oauth2/client_spec.rb
@@ -169,7 +169,7 @@
               end
             end
           end
-          header_params = {'headers' => { 'CustomHeader' => 'CustomHeader' }}
+          header_params = {'headers' => {'CustomHeader' => 'CustomHeader'}}
           client.auth_code.get_token('code', header_params)
         end
       end
@@ -184,7 +184,7 @@
               end
             end
           end
-          header_params = {headers: { 'CustomHeader' => 'CustomHeader' }}
+          header_params = {:headers => {'CustomHeader' => 'CustomHeader'}}
           client.auth_code.get_token('code', header_params)
         end
       end
@@ -199,7 +199,7 @@
               end
             end
           end
-          header_params = {'headers' => { 'CustomHeader' => 'CustomHeader' }}
+          header_params = {'headers' => {'CustomHeader' => 'CustomHeader'}}
           client.auth_code.get_token('code', header_params)
         end
       end
@@ -214,7 +214,7 @@
               end
             end
           end
-          header_params = {headers: { 'CustomHeader' => 'CustomHeader' }}
+          header_params = {:headers => {'CustomHeader' => 'CustomHeader'}}
           client.auth_code.get_token('code', header_params)
         end
       end
@@ -274,12 +274,13 @@
       end
     end
 
+    # rubocop:disable Style/RedundantBegin
     it 're-encodes response body in the error message' do
       begin
         subject.request(:get, '/ascii_8bit_encoding')
-      rescue StandardError => ex
-        expect(ex.message.encoding.name).to eq('UTF-8')
-        expect(ex.message).to eq("invalid_request: é\n{\"error\":\"invalid_request\",\"error_description\":\"��\"}")
+      rescue StandardError => e
+        expect(e.message.encoding.name).to eq('UTF-8')
+        expect(e.message).to eq("invalid_request: é\n{\"error\":\"invalid_request\",\"error_description\":\"��\"}")
       end
     end
 
@@ -302,12 +303,14 @@
         expect(e.to_s).to match(/unknown error/)
       end
     end
+    # rubocop:enable Style/RedundantBegin
 
     context 'with ENV' do
       include_context 'with stubbed env'
       before do
         stub_env('OAUTH_DEBUG' => 'true')
       end
+
       it 'outputs to $stdout when OAUTH_DEBUG=true' do
         output = capture(:stdout) do
           subject.request(:get, '/success')
@@ -315,7 +318,7 @@
         logs = [
           '-- request: GET https://api.example.com/success',
           '-- response: Status 200',
-          '-- response: Content-Type: "text/awesome"'
+          '-- response: Content-Type: "text/awesome"',
         ]
         expect(output).to include(*logs)
       end
@@ -348,6 +351,7 @@
       client = stubbed_client(:auth_scheme => :basic_auth) do |stub|
         stub.post('/oauth/token') do |env|
           raise Faraday::Adapter::Test::Stubs::NotFound unless env[:request_headers]['Authorization'] == OAuth2::Authenticator.encode_basic_auth('abc', 'def')
+
           [200, {'Content-Type' => 'application/json'}, MultiJson.encode('access_token' => 'the-token')]
         end
       end
@@ -355,7 +359,7 @@
     end
 
     describe 'extract_access_token option' do
-      let(:client) do 
+      let(:client) do
         client = stubbed_client(:extract_access_token => extract_access_token) do |stub|
           stub.post('/oauth/token') do
             [200, {'Content-Type' => 'application/json'}, MultiJson.encode('data' => {'access_token' => 'the-token'})]
@@ -363,7 +367,7 @@
         end
       end
 
-      context "with proc extract_access_token" do
+      context 'with proc extract_access_token' do
         let(:extract_access_token) do
           proc do |client, hash|
             token = hash['data']['access_token']
@@ -378,10 +382,10 @@
         end
       end
 
-      context "with depracted Class.from_hash option" do
+      context 'with depracted Class.from_hash option' do
         let(:extract_access_token) do
           CustomAccessToken = Class.new(AccessToken)
-          CustomAccessToken.define_singleton_method(:from_hash) do |client, hash| 
+          CustomAccessToken.define_singleton_method(:from_hash) do |client, hash|
             token = hash['data']['access_token']
             AccessToken.new(client, token, hash)
           end
diff --git a/spec/oauth2/response_spec.rb b/spec/oauth2/response_spec.rb
index ace9ac52..f402455a 100644
--- a/spec/oauth2/response_spec.rb
+++ b/spec/oauth2/response_spec.rb
@@ -8,8 +8,8 @@
 
     it 'returns the status, headers and body' do
       response = double('response', :headers => headers,
-                                    :status  => status,
-                                    :body    => body)
+                                    :status => status,
+                                    :body => body)
       subject = Response.new(response)
       expect(subject.headers).to eq(headers)
       expect(subject.status).to eq(status)
diff --git a/spec/oauth2/strategy/assertion_spec.rb b/spec/oauth2/strategy/assertion_spec.rb
index 36ea17de..a40220f4 100644
--- a/spec/oauth2/strategy/assertion_spec.rb
+++ b/spec/oauth2/strategy/assertion_spec.rb
@@ -22,8 +22,8 @@
 
   let(:params) do
     {
-        :hmac_secret => 'foo',
-        :exp => Time.now.utc.to_i + 3600
+      :hmac_secret => 'foo',
+      :exp => Time.now.utc.to_i + 3600,
     }
   end
 

From a7f949e70062b914744b8a8ee26cc5b9bea6546e Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Thu, 18 Mar 2021 14:39:35 -0600
Subject: [PATCH 033/163] CHANGELOG

---
 CHANGELOG.md | 1 +
 1 file changed, 1 insertion(+)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index e1e04a6a..eafc3a2f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file.
 
 ## unreleased
 
+- [#535](https://github.com/oauth-xx/oauth2/pull/535) - Compatibility with range of supported Ruby OpenSSL versions, Rubocop updates, Github Actions (@pboling)
 - [#518](https://github.com/oauth-xx/oauth2/pull/518) - Add extract_access_token option to OAuth2::Client (@jonspalmer)
 
 ## [1.4.4] - 2020-02-12

From 6743d0c64eaf560f5fc12f486f94087f069f4fa8 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Thu, 18 Mar 2021 14:40:34 -0600
Subject: [PATCH 034/163] Update Code of Conduct to v2.0

---
 CODE_OF_CONDUCT.md | 151 +++++++++++++++++++++++++++++++--------------
 1 file changed, 105 insertions(+), 46 deletions(-)

diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
index 395b407d..99ab478b 100644
--- a/CODE_OF_CONDUCT.md
+++ b/CODE_OF_CONDUCT.md
@@ -1,74 +1,133 @@
+
 # Contributor Covenant Code of Conduct
 
 ## Our Pledge
 
-In the interest of fostering an open and welcoming environment, we as
-contributors and maintainers pledge to making participation in our project and
-our community a harassment-free experience for everyone, regardless of age, body
-size, disability, ethnicity, gender identity and expression, level of experience,
-nationality, personal appearance, race, religion, or sexual identity and
-orientation.
+We as members, contributors, and leaders pledge to make participation in our
+community a harassment-free experience for everyone, regardless of age, body
+size, visible or invisible disability, ethnicity, sex characteristics, gender
+identity and expression, level of experience, education, socio-economic status,
+nationality, personal appearance, race, religion, or sexual identity
+and orientation.
+
+We pledge to act and interact in ways that contribute to an open, welcoming,
+diverse, inclusive, and healthy community.
 
 ## Our Standards
 
-Examples of behavior that contributes to creating a positive environment
-include:
+Examples of behavior that contributes to a positive environment for our
+community include:
 
-* Using welcoming and inclusive language
-* Being respectful of differing viewpoints and experiences
-* Gracefully accepting constructive criticism
-* Focusing on what is best for the community
-* Showing empathy towards other community members
+* Demonstrating empathy and kindness toward other people
+* Being respectful of differing opinions, viewpoints, and experiences
+* Giving and gracefully accepting constructive feedback
+* Accepting responsibility and apologizing to those affected by our mistakes,
+  and learning from the experience
+* Focusing on what is best not just for us as individuals, but for the
+  overall community
 
-Examples of unacceptable behavior by participants include:
+Examples of unacceptable behavior include:
 
-* The use of sexualized language or imagery and unwelcome sexual attention or
-advances
-* Trolling, insulting/derogatory comments, and personal or political attacks
+* The use of sexualized language or imagery, and sexual attention or
+  advances of any kind
+* Trolling, insulting or derogatory comments, and personal or political attacks
 * Public or private harassment
-* Publishing others' private information, such as a physical or electronic
-  address, without explicit permission
+* Publishing others' private information, such as a physical or email
+  address, without their explicit permission
 * Other conduct which could reasonably be considered inappropriate in a
   professional setting
 
-## Our Responsibilities
+## Enforcement Responsibilities
 
-Project maintainers are responsible for clarifying the standards of acceptable
-behavior and are expected to take appropriate and fair corrective action in
-response to any instances of unacceptable behavior.
+Community leaders are responsible for clarifying and enforcing our standards of
+acceptable behavior and will take appropriate and fair corrective action in
+response to any behavior that they deem inappropriate, threatening, offensive,
+or harmful.
 
-Project maintainers have the right and responsibility to remove, edit, or
-reject comments, commits, code, wiki edits, issues, and other contributions
-that are not aligned to this Code of Conduct, or to ban temporarily or
-permanently any contributor for other behaviors that they deem inappropriate,
-threatening, offensive, or harmful.
+Community leaders have the right and responsibility to remove, edit, or reject
+comments, commits, code, wiki edits, issues, and other contributions that are
+not aligned to this Code of Conduct, and will communicate reasons for moderation
+decisions when appropriate.
 
 ## Scope
 
-This Code of Conduct applies both within project spaces and in public spaces
-when an individual is representing the project or its community. Examples of
-representing a project or community include using an official project e-mail
-address, posting via an official social media account, or acting as an appointed
-representative at an online or offline event. Representation of a project may be
-further defined and clarified by project maintainers.
+This Code of Conduct applies within all community spaces, and also applies when
+an individual is officially representing the community in public spaces.
+Examples of representing our community include using an official e-mail address,
+posting via an official social media account, or acting as an appointed
+representative at an online or offline event.
 
 ## Enforcement
 
 Instances of abusive, harassing, or otherwise unacceptable behavior may be
-reported by contacting the project team at peter.boling@gmail.com. All
-complaints will be reviewed and investigated and will result in a response that
-is deemed necessary and appropriate to the circumstances. The project team is
-obligated to maintain confidentiality with regard to the reporter of an incident.
-Further details of specific enforcement policies may be posted separately.
+reported to the community leaders responsible for enforcement at
+[INSERT CONTACT METHOD].
+All complaints will be reviewed and investigated promptly and fairly.
+
+All community leaders are obligated to respect the privacy and security of the
+reporter of any incident.
+
+## Enforcement Guidelines
+
+Community leaders will follow these Community Impact Guidelines in determining
+the consequences for any action they deem in violation of this Code of Conduct:
+
+### 1. Correction
+
+**Community Impact**: Use of inappropriate language or other behavior deemed
+unprofessional or unwelcome in the community.
+
+**Consequence**: A private, written warning from community leaders, providing
+clarity around the nature of the violation and an explanation of why the
+behavior was inappropriate. A public apology may be requested.
+
+### 2. Warning
 
-Project maintainers who do not follow or enforce the Code of Conduct in good
-faith may face temporary or permanent repercussions as determined by other
-members of the project's leadership.
+**Community Impact**: A violation through a single incident or series
+of actions.
+
+**Consequence**: A warning with consequences for continued behavior. No
+interaction with the people involved, including unsolicited interaction with
+those enforcing the Code of Conduct, for a specified period of time. This
+includes avoiding interactions in community spaces as well as external channels
+like social media. Violating these terms may lead to a temporary or
+permanent ban.
+
+### 3. Temporary Ban
+
+**Community Impact**: A serious violation of community standards, including
+sustained inappropriate behavior.
+
+**Consequence**: A temporary ban from any sort of interaction or public
+communication with the community for a specified period of time. No public or
+private interaction with the people involved, including unsolicited interaction
+with those enforcing the Code of Conduct, is allowed during this period.
+Violating these terms may lead to a permanent ban.
+
+### 4. Permanent Ban
+
+**Community Impact**: Demonstrating a pattern of violation of community
+standards, including sustained inappropriate behavior,  harassment of an
+individual, or aggression toward or disparagement of classes of individuals.
+
+**Consequence**: A permanent ban from any sort of public interaction within
+the community.
 
 ## Attribution
 
-This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
-available at [http://contributor-covenant.org/version/1/4][version]
+This Code of Conduct is adapted from the [Contributor Covenant][homepage],
+version 2.0, available at
+[https://www.contributor-covenant.org/version/2/0/code_of_conduct.html][v2.0].
+
+Community Impact Guidelines were inspired by
+[Mozilla's code of conduct enforcement ladder][Mozilla CoC].
+
+For answers to common questions about this code of conduct, see the FAQ at
+[https://www.contributor-covenant.org/faq][FAQ]. Translations are available
+at [https://www.contributor-covenant.org/translations][translations].
 
-[homepage]: http://contributor-covenant.org
-[version]: http://contributor-covenant.org/version/1/4/
+[homepage]: https://www.contributor-covenant.org
+[v2.0]: https://www.contributor-covenant.org/version/2/0/code_of_conduct.html
+[Mozilla CoC]: https://github.com/mozilla/diversity
+[FAQ]: https://www.contributor-covenant.org/faq
+[translations]: https://www.contributor-covenant.org/translations

From 24961fcbad975301e489888e9a53e2456ff6a619 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Thu, 18 Mar 2021 15:46:50 -0600
Subject: [PATCH 035/163] Prep for 1.4.5 release

---
 CHANGELOG.md | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index eafc3a2f..6e718feb 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,6 +3,8 @@ All notable changes to this project will be documented in this file.
 
 ## unreleased
 
+## [1.4.5] - 2020-03-18
+
 - [#535](https://github.com/oauth-xx/oauth2/pull/535) - Compatibility with range of supported Ruby OpenSSL versions, Rubocop updates, Github Actions (@pboling)
 - [#518](https://github.com/oauth-xx/oauth2/pull/518) - Add extract_access_token option to OAuth2::Client (@jonspalmer)
 

From 8fcf3d7c1638bc97df8fbffaee63977a88d6c070 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Thu, 18 Mar 2021 15:53:03 -0600
Subject: [PATCH 036/163] Add a VERSION constant

---
 .rspec                                          | 2 ++
 lib/oauth2/version.rb                           | 1 +
 spec/oauth2/access_token_spec.rb                | 2 --
 spec/oauth2/authenticator_spec.rb               | 2 --
 spec/oauth2/mac_token_spec.rb                   | 2 --
 spec/oauth2/response_spec.rb                    | 2 --
 spec/oauth2/strategy/assertion_spec.rb          | 2 --
 spec/oauth2/strategy/auth_code_spec.rb          | 2 --
 spec/oauth2/strategy/base_spec.rb               | 2 --
 spec/oauth2/strategy/client_credentials_spec.rb | 2 --
 spec/oauth2/strategy/implicit_spec.rb           | 2 --
 spec/oauth2/strategy/password_spec.rb           | 2 --
 spec/oauth2/version_spec.rb                     | 7 +++++++
 13 files changed, 10 insertions(+), 20 deletions(-)
 create mode 100644 spec/oauth2/version_spec.rb

diff --git a/.rspec b/.rspec
index 09127182..3629a4a1 100644
--- a/.rspec
+++ b/.rspec
@@ -1,2 +1,4 @@
 --color
 --order random
+--require helper
+--format=documentation
diff --git a/lib/oauth2/version.rb b/lib/oauth2/version.rb
index cc1365f4..3d6984fb 100644
--- a/lib/oauth2/version.rb
+++ b/lib/oauth2/version.rb
@@ -1,5 +1,6 @@
 module OAuth2
   module Version
+    VERSION = to_s
   module_function
 
     # The major version
diff --git a/spec/oauth2/access_token_spec.rb b/spec/oauth2/access_token_spec.rb
index 93890491..868aaf8e 100644
--- a/spec/oauth2/access_token_spec.rb
+++ b/spec/oauth2/access_token_spec.rb
@@ -1,5 +1,3 @@
-require 'helper'
-
 describe AccessToken do
   subject { described_class.new(client, token) }
 
diff --git a/spec/oauth2/authenticator_spec.rb b/spec/oauth2/authenticator_spec.rb
index e4d60482..48cbac9b 100644
--- a/spec/oauth2/authenticator_spec.rb
+++ b/spec/oauth2/authenticator_spec.rb
@@ -1,5 +1,3 @@
-require 'helper'
-
 describe OAuth2::Authenticator do
   subject do
     described_class.new(client_id, client_secret, mode)
diff --git a/spec/oauth2/mac_token_spec.rb b/spec/oauth2/mac_token_spec.rb
index add5f72e..b18c2469 100644
--- a/spec/oauth2/mac_token_spec.rb
+++ b/spec/oauth2/mac_token_spec.rb
@@ -1,5 +1,3 @@
-require 'helper'
-
 describe MACToken do
   subject { described_class.new(client, token, 'abc123') }
 
diff --git a/spec/oauth2/response_spec.rb b/spec/oauth2/response_spec.rb
index f402455a..9672b52c 100644
--- a/spec/oauth2/response_spec.rb
+++ b/spec/oauth2/response_spec.rb
@@ -1,5 +1,3 @@
-require 'helper'
-
 describe OAuth2::Response do
   describe '#initialize' do
     let(:status) { 200 }
diff --git a/spec/oauth2/strategy/assertion_spec.rb b/spec/oauth2/strategy/assertion_spec.rb
index a40220f4..148e3e3a 100644
--- a/spec/oauth2/strategy/assertion_spec.rb
+++ b/spec/oauth2/strategy/assertion_spec.rb
@@ -1,5 +1,3 @@
-require 'helper'
-
 describe OAuth2::Strategy::Assertion do
   subject { client.assertion }
 
diff --git a/spec/oauth2/strategy/auth_code_spec.rb b/spec/oauth2/strategy/auth_code_spec.rb
index bcb1984f..36cd3a5a 100644
--- a/spec/oauth2/strategy/auth_code_spec.rb
+++ b/spec/oauth2/strategy/auth_code_spec.rb
@@ -1,7 +1,5 @@
 # encoding: utf-8
 
-require 'helper'
-
 describe OAuth2::Strategy::AuthCode do
   subject { client.auth_code }
 
diff --git a/spec/oauth2/strategy/base_spec.rb b/spec/oauth2/strategy/base_spec.rb
index fb59e963..67c66d1a 100644
--- a/spec/oauth2/strategy/base_spec.rb
+++ b/spec/oauth2/strategy/base_spec.rb
@@ -1,5 +1,3 @@
-require 'helper'
-
 describe OAuth2::Strategy::Base do
   it 'initializes with a Client' do
     expect { described_class.new(OAuth2::Client.new('abc', 'def')) }.not_to raise_error
diff --git a/spec/oauth2/strategy/client_credentials_spec.rb b/spec/oauth2/strategy/client_credentials_spec.rb
index 11d3b525..4f91bfd5 100644
--- a/spec/oauth2/strategy/client_credentials_spec.rb
+++ b/spec/oauth2/strategy/client_credentials_spec.rb
@@ -1,5 +1,3 @@
-require 'helper'
-
 describe OAuth2::Strategy::ClientCredentials do
   subject { client.client_credentials }
 
diff --git a/spec/oauth2/strategy/implicit_spec.rb b/spec/oauth2/strategy/implicit_spec.rb
index 7f48ec04..c4df8ebd 100644
--- a/spec/oauth2/strategy/implicit_spec.rb
+++ b/spec/oauth2/strategy/implicit_spec.rb
@@ -1,5 +1,3 @@
-require 'helper'
-
 describe OAuth2::Strategy::Implicit do
   subject { client.implicit }
 
diff --git a/spec/oauth2/strategy/password_spec.rb b/spec/oauth2/strategy/password_spec.rb
index 0c9a07dd..c8b006aa 100644
--- a/spec/oauth2/strategy/password_spec.rb
+++ b/spec/oauth2/strategy/password_spec.rb
@@ -1,5 +1,3 @@
-require 'helper'
-
 describe OAuth2::Strategy::Password do
   subject { client.password }
 
diff --git a/spec/oauth2/version_spec.rb b/spec/oauth2/version_spec.rb
new file mode 100644
index 00000000..27cba9e0
--- /dev/null
+++ b/spec/oauth2/version_spec.rb
@@ -0,0 +1,7 @@
+describe OAuth2::Version do
+  context 'Constant' do
+    it 'is a sting' do
+      expect(OAuth2::Version::VERSION).to be_a(String)
+    end
+  end
+end
\ No newline at end of file

From e395da8299cdef70138667656f68e2fbdc3d5402 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Thu, 18 Mar 2021 15:54:23 -0600
Subject: [PATCH 037/163] Improve version

---
 oauth2.gemspec | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/oauth2.gemspec b/oauth2.gemspec
index 9c58103b..86a825c7 100644
--- a/oauth2.gemspec
+++ b/oauth2.gemspec
@@ -20,7 +20,7 @@ Gem::Specification.new do |spec|
   spec.required_ruby_version = '>= 1.9.0'
   spec.required_rubygems_version = '>= 1.3.5'
   spec.summary       = 'A Ruby wrapper for the OAuth 2.0 protocol.'
-  spec.version       = OAuth2::Version
+  spec.version       = OAuth2::Version.to_s
 
   spec.metadata = {
     'bug_tracker_uri' => 'https://github.com/oauth-xx/oauth2/issues',

From 5f54ebec470aec2043790ef1b7e2f6579fcfc205 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Thu, 18 Mar 2021 16:01:46 -0600
Subject: [PATCH 038/163] Typo in CHANGELOG

---
 CHANGELOG.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6e718feb..17811d16 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,7 +3,7 @@ All notable changes to this project will be documented in this file.
 
 ## unreleased
 
-## [1.4.5] - 2020-03-18
+## [1.4.5] - 2021-03-18
 
 - [#535](https://github.com/oauth-xx/oauth2/pull/535) - Compatibility with range of supported Ruby OpenSSL versions, Rubocop updates, Github Actions (@pboling)
 - [#518](https://github.com/oauth-xx/oauth2/pull/518) - Add extract_access_token option to OAuth2::Client (@jonspalmer)

From c2bc396076acc0aa8409dbb348cb3a04c145b470 Mon Sep 17 00:00:00 2001
From: Anders Carling <lowe@lowe.nu>
Date: Fri, 19 Mar 2021 03:13:43 +0100
Subject: [PATCH 039/163] Fix crash in OAuth2::Client#get_token (#537)

`def build_access_token` as not found as it was implemented on OAuth2 instead of OAuth2::Client
---
 lib/oauth2/client.rb | 32 ++++++++++++++++----------------
 1 file changed, 16 insertions(+), 16 deletions(-)

diff --git a/lib/oauth2/client.rb b/lib/oauth2/client.rb
index 1cba2402..f98a9f37 100644
--- a/lib/oauth2/client.rb
+++ b/lib/oauth2/client.rb
@@ -231,27 +231,27 @@ def redirection_params
         {}
       end
     end
-  end
 
-  DEFAULT_EXTRACT_ACCESS_TOKEN = proc do |client, hash|
-    token = hash.delete('access_token') || hash.delete(:access_token)
-    token && AccessToken.new(client, token, hash)
-  end
+    DEFAULT_EXTRACT_ACCESS_TOKEN = proc do |client, hash|
+      token = hash.delete('access_token') || hash.delete(:access_token)
+      token && AccessToken.new(client, token, hash)
+    end
 
-private
+  private
 
-  def build_access_token(response, access_token_opts, extract_access_token)
-    parsed_response = response.parsed.dup
-    return unless parsed_response.is_a?(Hash)
+    def build_access_token(response, access_token_opts, extract_access_token)
+      parsed_response = response.parsed.dup
+      return unless parsed_response.is_a?(Hash)
 
-    hash = parsed_response.merge(access_token_opts)
+      hash = parsed_response.merge(access_token_opts)
 
-    # Provide backwards compatibility for old AcessToken.form_hash pattern
-    # Should be deprecated in 2.x
-    if extract_access_token.is_a?(Class) && extract_access_token.respond_to?(:from_hash)
-      extract_access_token.from_hash(self, hash)
-    else
-      extract_access_token.call(self, hash)
+      # Provide backwards compatibility for old AcessToken.form_hash pattern
+      # Should be deprecated in 2.x
+      if extract_access_token.is_a?(Class) && extract_access_token.respond_to?(:from_hash)
+        extract_access_token.from_hash(self, hash)
+      else
+        extract_access_token.call(self, hash)
+      end
     end
   end
 end

From ad62ca1e87b5a75c8fc3a0f8aa7af6ddd5a0d054 Mon Sep 17 00:00:00 2001
From: Anders Carling <lowe@lowe.nu>
Date: Fri, 19 Mar 2021 03:16:39 +0100
Subject: [PATCH 040/163] Remove reliance on globally included OAuth2 in tests
 for version 1.4 (#538)

---
 lib/oauth2/client.rb             | 1 +
 spec/helper.rb                   | 5 -----
 spec/oauth2/access_token_spec.rb | 4 ++--
 spec/oauth2/client_spec.rb       | 6 +++---
 spec/oauth2/mac_token_spec.rb    | 6 +++---
 spec/oauth2/response_spec.rb     | 8 ++++----
 6 files changed, 13 insertions(+), 17 deletions(-)

diff --git a/lib/oauth2/client.rb b/lib/oauth2/client.rb
index f98a9f37..a3c64d10 100644
--- a/lib/oauth2/client.rb
+++ b/lib/oauth2/client.rb
@@ -166,6 +166,7 @@ def get_token(params, access_token_opts = {}, extract_access_token = options[:ex
       access_token = begin
         build_access_token(response, access_token_opts, extract_access_token)
       rescue StandardError
+        raise
         nil
       end
 
diff --git a/spec/helper.rb b/spec/helper.rb
index 5ce4d82f..8b64d420 100644
--- a/spec/helper.rb
+++ b/spec/helper.rb
@@ -30,11 +30,6 @@
 
 Faraday.default_adapter = :test
 
-# This is dangerous - HERE BE DRAGONS.
-# It allows us to refer to classes without the namespace, but at what cost?!?
-# TODO: Refactor to use explicit references everywhere
-include OAuth2
-
 RSpec.configure do |conf|
   conf.include SilentStream
 end
diff --git a/spec/oauth2/access_token_spec.rb b/spec/oauth2/access_token_spec.rb
index 868aaf8e..c586bc4c 100644
--- a/spec/oauth2/access_token_spec.rb
+++ b/spec/oauth2/access_token_spec.rb
@@ -1,10 +1,10 @@
-describe AccessToken do
+describe OAuth2::AccessToken do
   subject { described_class.new(client, token) }
 
   let(:token) { 'monkey' }
   let(:refresh_body) { MultiJson.encode(:access_token => 'refreshed_foo', :expires_in => 600, :refresh_token => 'refresh_bar') }
   let(:client) do
-    Client.new('abc', 'def', :site => 'https://api.example.com') do |builder|
+    OAuth2::Client.new('abc', 'def', :site => 'https://api.example.com') do |builder|
       builder.request :url_encoded
       builder.adapter :test do |stub|
         VERBS.each do |verb|
diff --git a/spec/oauth2/client_spec.rb b/spec/oauth2/client_spec.rb
index 46f75b4b..583ea12f 100644
--- a/spec/oauth2/client_spec.rb
+++ b/spec/oauth2/client_spec.rb
@@ -371,7 +371,7 @@
         let(:extract_access_token) do
           proc do |client, hash|
             token = hash['data']['access_token']
-            AccessToken.new(client, token, hash)
+            OAuth2::AccessToken.new(client, token, hash)
           end
         end
 
@@ -384,10 +384,10 @@
 
       context 'with depracted Class.from_hash option' do
         let(:extract_access_token) do
-          CustomAccessToken = Class.new(AccessToken)
+          CustomAccessToken = Class.new(OAuth2::AccessToken)
           CustomAccessToken.define_singleton_method(:from_hash) do |client, hash|
             token = hash['data']['access_token']
-            AccessToken.new(client, token, hash)
+            OAuth2::AccessToken.new(client, token, hash)
           end
           CustomAccessToken
         end
diff --git a/spec/oauth2/mac_token_spec.rb b/spec/oauth2/mac_token_spec.rb
index b18c2469..0685350f 100644
--- a/spec/oauth2/mac_token_spec.rb
+++ b/spec/oauth2/mac_token_spec.rb
@@ -1,9 +1,9 @@
-describe MACToken do
+describe OAuth2::MACToken do
   subject { described_class.new(client, token, 'abc123') }
 
   let(:token) { 'monkey' }
   let(:client) do
-    Client.new('abc', 'def', :site => 'https://api.example.com') do |builder|
+    OAuth2::Client.new('abc', 'def', :site => 'https://api.example.com') do |builder|
       builder.request :url_encoded
       builder.adapter :test do |stub|
         VERBS.each do |verb|
@@ -89,7 +89,7 @@
     subject { described_class.from_access_token(access_token, 'hello') }
 
     let(:access_token) do
-      AccessToken.new(
+      OAuth2::AccessToken.new(
         client, token,
         :expires_at => 1,
         :expires_in => 1,
diff --git a/spec/oauth2/response_spec.rb b/spec/oauth2/response_spec.rb
index 9672b52c..3171fd26 100644
--- a/spec/oauth2/response_spec.rb
+++ b/spec/oauth2/response_spec.rb
@@ -8,7 +8,7 @@
       response = double('response', :headers => headers,
                                     :status => status,
                                     :body => body)
-      subject = Response.new(response)
+      subject = described_class.new(response)
       expect(subject.headers).to eq(headers)
       expect(subject.status).to eq(status)
       expect(subject.body).to eq(body)
@@ -43,7 +43,7 @@
       headers = {'Content-Type' => 'application/x-www-form-urlencoded'}
       body = 'foo=bar&answer=42'
       response = double('response', :headers => headers, :body => body)
-      subject = Response.new(response)
+      subject = described_class.new(response)
       expect(subject.parsed.keys.size).to eq(2)
       expect(subject.parsed['foo']).to eq('bar')
       expect(subject.parsed['answer']).to eq('42')
@@ -53,7 +53,7 @@
       headers = {'Content-Type' => 'application/json'}
       body = MultiJson.encode(:foo => 'bar', :answer => 42)
       response = double('response', :headers => headers, :body => body)
-      subject = Response.new(response)
+      subject = described_class.new(response)
       expect(subject.parsed.keys.size).to eq(2)
       expect(subject.parsed['foo']).to eq('bar')
       expect(subject.parsed['answer']).to eq(42)
@@ -69,7 +69,7 @@
       expect(MultiJson).not_to receive(:load)
       expect(Rack::Utils).not_to receive(:parse_query)
 
-      subject = Response.new(response)
+      subject = described_class.new(response)
       expect(subject.parsed).to be_nil
     end
   end

From 7eb91581969c447c075f89591838b993b3228b77 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Fri, 19 Mar 2021 09:28:16 +0700
Subject: [PATCH 041/163] Add VERSION constant (#540)

* Add VERSION constant

* Use :raise_errors option to have error raised
---
 CHANGELOG.md                | 6 ++++++
 lib/oauth2/client.rb        | 1 -
 lib/oauth2/version.rb       | 1 +
 spec/oauth2/version_spec.rb | 8 +++-----
 4 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 17811d16..1782b22f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,6 +3,12 @@ All notable changes to this project will be documented in this file.
 
 ## unreleased
 
+## [1.4.6] - 2021-03-18
+
+
+- [#537](https://github.com/oauth-xx/oauth2/pull/537) - Fix crash in OAuth2::Client#get_token (@anderscarling)
+- [#538](https://github.com/oauth-xx/oauth2/pull/538) - Remove reliance on globally included OAuth2 in tests for version 1.4 (@anderscarling)
+
 ## [1.4.5] - 2021-03-18
 
 - [#535](https://github.com/oauth-xx/oauth2/pull/535) - Compatibility with range of supported Ruby OpenSSL versions, Rubocop updates, Github Actions (@pboling)
diff --git a/lib/oauth2/client.rb b/lib/oauth2/client.rb
index a3c64d10..f98a9f37 100644
--- a/lib/oauth2/client.rb
+++ b/lib/oauth2/client.rb
@@ -166,7 +166,6 @@ def get_token(params, access_token_opts = {}, extract_access_token = options[:ex
       access_token = begin
         build_access_token(response, access_token_opts, extract_access_token)
       rescue StandardError
-        raise
         nil
       end
 
diff --git a/lib/oauth2/version.rb b/lib/oauth2/version.rb
index 3d6984fb..6b7b63e0 100644
--- a/lib/oauth2/version.rb
+++ b/lib/oauth2/version.rb
@@ -1,6 +1,7 @@
 module OAuth2
   module Version
     VERSION = to_s
+
   module_function
 
     # The major version
diff --git a/spec/oauth2/version_spec.rb b/spec/oauth2/version_spec.rb
index 27cba9e0..3e395eac 100644
--- a/spec/oauth2/version_spec.rb
+++ b/spec/oauth2/version_spec.rb
@@ -1,7 +1,5 @@
 describe OAuth2::Version do
-  context 'Constant' do
-    it 'is a sting' do
-      expect(OAuth2::Version::VERSION).to be_a(String)
-    end
+  it 'VERSION a sting' do
+    expect(OAuth2::Version::VERSION).to be_a(String)
   end
-end
\ No newline at end of file
+end

From b13ae4be0f1ee8ea56bffb209457cfdb834d6eee Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Thu, 18 Mar 2021 20:33:22 -0600
Subject: [PATCH 042/163] Document 1.4.6 release

---
 README.md | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/README.md b/README.md
index 8cff087e..c04bf67c 100644
--- a/README.md
+++ b/README.md
@@ -4,6 +4,8 @@ If you need the readme for a released version of the gem please find it below:
 
 | Version  | Release Date | Readme                                                   |
 |----------|--------------|----------------------------------------------------------|
+| 1.4.6    | Mar 18, 2021 | https://github.com/oauth-xx/oauth2/blob/v1.4.6/README.md |
+| 1.4.5    | Mar 18, 2021 | https://github.com/oauth-xx/oauth2/blob/v1.4.5/README.md |
 | 1.4.4    | Feb 12, 2020 | https://github.com/oauth-xx/oauth2/blob/v1.4.4/README.md |
 | 1.4.3    | Jan 29, 2020 | https://github.com/oauth-xx/oauth2/blob/v1.4.3/README.md |
 | 1.4.2    | Oct 1, 2019  | https://github.com/oauth-xx/oauth2/blob/v1.4.2/README.md |
@@ -20,6 +22,7 @@ If you need the readme for a released version of the gem please find it below:
 [![Total Downloads](https://img.shields.io/gem/dt/oauth2.svg)][gem]
 [![Downloads Today](https://img.shields.io/gem/rt/oauth2.svg)][gem]
 [![Build Status](https://travis-ci.org/oauth-xx/oauth2.svg?branch=1-4-stable)][travis]
+[![Build Status](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Factions-badge.atrox.dev%2Foauth-xx%2Foauth2%2Fbadge&style=flat)][github-actions]
 [![Test Coverage](https://api.codeclimate.com/v1/badges/688c612528ff90a46955/test_coverage)][codeclimate-coverage]
 [![Maintainability](https://api.codeclimate.com/v1/badges/688c612528ff90a46955/maintainability)][codeclimate-maintainability]
 [![Depfu](https://badges.depfu.com/badges/6d34dc1ba682bbdf9ae2a97848241743/count.svg)][depfu]
@@ -30,6 +33,7 @@ If you need the readme for a released version of the gem please find it below:
 
 [gem]: https://rubygems.org/gems/oauth2
 [travis]: http://travis-ci.org/oauth-xx/oauth2
+[github-actions]: https://actions-badge.atrox.dev/oauth-xx/oauth2/goto
 [coveralls]: https://coveralls.io/r/oauth-xx/oauth2
 [codeclimate-maintainability]: https://codeclimate.com/github/oauth-xx/oauth2/maintainability
 [codeclimate-coverage]: https://codeclimate.com/github/oauth-xx/oauth2/test_coverage

From 92544cf6fdd1cc93fbea67beec9de8dc9d1fe041 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Thu, 18 Mar 2021 20:34:43 -0600
Subject: [PATCH 043/163] Release 1.4.6

---
 lib/oauth2/version.rb | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/oauth2/version.rb b/lib/oauth2/version.rb
index 6b7b63e0..2efb2a36 100644
--- a/lib/oauth2/version.rb
+++ b/lib/oauth2/version.rb
@@ -22,7 +22,7 @@ def minor
     #
     # @return [Integer]
     def patch
-      5
+      6
     end
 
     # The pre-release version, if any

From 8b399a3d61eabaaa8c25ee6e0120801095c409ab Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Thu, 18 Mar 2021 20:37:16 -0600
Subject: [PATCH 044/163] CHANGELOG for 1.4.6

---
 CHANGELOG.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1782b22f..b36e097b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file.
 
 ## [1.4.6] - 2021-03-18
 
-
+- [#540](https://github.com/oauth-xx/oauth2/pull/540) - Add VERSION constant (@pboling)
 - [#537](https://github.com/oauth-xx/oauth2/pull/537) - Fix crash in OAuth2::Client#get_token (@anderscarling)
 - [#538](https://github.com/oauth-xx/oauth2/pull/538) - Remove reliance on globally included OAuth2 in tests for version 1.4 (@anderscarling)
 

From 9f2275c0f7d0291b8693e4df7f2a0fd6a19c8ca0 Mon Sep 17 00:00:00 2001
From: dobon <dobon@users.noreply.github.com>
Date: Thu, 18 Mar 2021 20:39:54 -0700
Subject: [PATCH 045/163] backport pull request #533 to 1-4-stable branch.
 (#541)

Co-authored-by: dobon <>
---
 lib/oauth2/access_token.rb       |  8 +++----
 spec/oauth2/access_token_spec.rb | 36 +++++++++++++++++++++++++-------
 2 files changed, 31 insertions(+), 13 deletions(-)

diff --git a/lib/oauth2/access_token.rb b/lib/oauth2/access_token.rb
index db8c2239..228b99e6 100644
--- a/lib/oauth2/access_token.rb
+++ b/lib/oauth2/access_token.rb
@@ -173,11 +173,9 @@ def configure_authentication!(opts) # rubocop:disable Metrics/AbcSize
     end
 
     def convert_expires_at(expires_at)
-      expires_at_i = expires_at.to_i
-      return expires_at_i if expires_at_i > Time.now.utc.to_i
-      return Time.parse(expires_at).to_i if expires_at.is_a?(String)
-
-      expires_at_i
+      Time.iso8601(expires_at.to_s).to_i
+    rescue ArgumentError
+      expires_at.to_i
     end
   end
 end
diff --git a/spec/oauth2/access_token_spec.rb b/spec/oauth2/access_token_spec.rb
index c586bc4c..01ea3db5 100644
--- a/spec/oauth2/access_token_spec.rb
+++ b/spec/oauth2/access_token_spec.rb
@@ -50,7 +50,7 @@ def assert_initialized_token(target) # rubocop:disable Metrics/AbcSize
       expect(hash).to eq(hash_before)
     end
 
-    it 'initalizes with a form-urlencoded key/value string' do
+    it 'initializes with a form-urlencoded key/value string' do
       kvform = "access_token=#{token}&expires_at=#{Time.now.to_i + 200}&foo=bar"
       target = described_class.from_kvform(client, kvform)
       assert_initialized_token(target)
@@ -70,13 +70,33 @@ def assert_initialized_token(target) # rubocop:disable Metrics/AbcSize
       expect(opts).to eq(opts_before)
     end
 
-    it 'initializes with a string expires_at' do
-      future = Time.now.utc + 100_000
-      hash = {:access_token => token, :expires_at => future.iso8601, 'foo' => 'bar'}
-      target = described_class.from_hash(client, hash)
-      assert_initialized_token(target)
-      expect(target.expires_at).to be_a(Integer)
-      expect(target.expires_at).to eql(future.to_i)
+    describe 'expires_at' do
+      let(:expires_at) { 1_361_396_829 }
+      let(:hash) do
+        {
+          :access_token => token,
+          :expires_at => expires_at.to_s,
+          'foo' => 'bar',
+        }
+      end
+
+      it 'initializes with an integer timestamp expires_at' do
+        target = described_class.from_hash(client, hash.merge(expires_at: expires_at))
+        assert_initialized_token(target)
+        expect(target.expires_at).to eql(expires_at)
+      end
+
+      it 'initializes with a string timestamp expires_at' do
+        target = described_class.from_hash(client, hash)
+        assert_initialized_token(target)
+        expect(target.expires_at).to eql(expires_at)
+      end
+
+      it 'initializes with a string time expires_at' do
+        target = described_class.from_hash(client, hash.merge(expires_at: Time.at(expires_at).iso8601))
+        assert_initialized_token(target)
+        expect(target.expires_at).to eql(expires_at)
+      end
     end
   end
 

From 59b937b7c8b6c1067e63695be875f56020aa3c89 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Thu, 18 Mar 2021 21:41:21 -0600
Subject: [PATCH 046/163] Support older rubies

---
 spec/oauth2/access_token_spec.rb | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/spec/oauth2/access_token_spec.rb b/spec/oauth2/access_token_spec.rb
index 01ea3db5..3aa34395 100644
--- a/spec/oauth2/access_token_spec.rb
+++ b/spec/oauth2/access_token_spec.rb
@@ -81,7 +81,7 @@ def assert_initialized_token(target) # rubocop:disable Metrics/AbcSize
       end
 
       it 'initializes with an integer timestamp expires_at' do
-        target = described_class.from_hash(client, hash.merge(expires_at: expires_at))
+        target = described_class.from_hash(client, hash.merge(:expires_at => expires_at))
         assert_initialized_token(target)
         expect(target.expires_at).to eql(expires_at)
       end
@@ -93,7 +93,7 @@ def assert_initialized_token(target) # rubocop:disable Metrics/AbcSize
       end
 
       it 'initializes with a string time expires_at' do
-        target = described_class.from_hash(client, hash.merge(expires_at: Time.at(expires_at).iso8601))
+        target = described_class.from_hash(client, hash.merge(:expires_at => Time.at(expires_at).iso8601))
         assert_initialized_token(target)
         expect(target.expires_at).to eql(expires_at)
       end

From 9d76cc9c41315060336c56ea7d11e19221ff780d Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Thu, 18 Mar 2021 21:43:40 -0600
Subject: [PATCH 047/163] CHANGELOG

---
 CHANGELOG.md | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index b36e097b..ee308fb8 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,6 +3,10 @@ All notable changes to this project will be documented in this file.
 
 ## unreleased
 
+## [1.4.7] - 2021-03-18
+
+- [#541](https://github.com/oauth-xx/oauth2/pull/541) - Backport fix to expires_at handling [#533](https://github.com/oauth-xx/oauth2/pull/533) to 1-4-stable branch. (@dobon)
+
 ## [1.4.6] - 2021-03-18
 
 - [#540](https://github.com/oauth-xx/oauth2/pull/540) - Add VERSION constant (@pboling)

From 662e2e68c43bd1bdc8b2183f42e5f6b03f75716f Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Thu, 18 Mar 2021 21:47:48 -0600
Subject: [PATCH 048/163] Improved VERSION; bump to 1.4.7

---
 lib/oauth2/version.rb       | 10 +++++++---
 spec/oauth2/version_spec.rb | 24 +++++++++++++++++++++---
 2 files changed, 28 insertions(+), 6 deletions(-)

diff --git a/lib/oauth2/version.rb b/lib/oauth2/version.rb
index 2efb2a36..9dba3aa2 100644
--- a/lib/oauth2/version.rb
+++ b/lib/oauth2/version.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module OAuth2
   module Version
     VERSION = to_s
@@ -22,12 +24,12 @@ def minor
     #
     # @return [Integer]
     def patch
-      6
+      7
     end
 
     # The pre-release version, if any
     #
-    # @return [Integer, NilClass]
+    # @return [String, NilClass]
     def pre
       nil
     end
@@ -55,7 +57,9 @@ def to_a
     #
     # @return [String]
     def to_s
-      to_a.join('.')
+      v = [major, minor, patch].compact.join('.')
+      v += "-#{pre}" if pre
+      v
     end
   end
 end
diff --git a/spec/oauth2/version_spec.rb b/spec/oauth2/version_spec.rb
index 3e395eac..854f1bc0 100644
--- a/spec/oauth2/version_spec.rb
+++ b/spec/oauth2/version_spec.rb
@@ -1,5 +1,23 @@
-describe OAuth2::Version do
-  it 'VERSION a sting' do
-    expect(OAuth2::Version::VERSION).to be_a(String)
+# frozen_string_literal: true
+
+RSpec.describe OAuth2::Version do
+  it 'has a version number' do
+    expect(described_class).not_to be nil
+  end
+
+  it 'can be a string' do
+    expect(described_class.to_s).to be_a(String)
+  end
+
+  it 'allows Constant access' do
+    expect(described_class::VERSION).to be_a(String)
+  end
+
+  it 'is greater than 0.1.0' do
+    expect(Gem::Version.new(described_class) > Gem::Version.new('0.1.0')).to be(true)
+  end
+
+  it 'is not a pre-release' do
+    expect(Gem::Version.new(described_class).prerelease?).to be(false)
   end
 end

From 55da82765355592efce03cb9d37dcde915a5bf7b Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Thu, 18 Mar 2021 21:48:56 -0600
Subject: [PATCH 049/163] Document release 1.4.7

---
 README.md | 1 +
 1 file changed, 1 insertion(+)

diff --git a/README.md b/README.md
index c04bf67c..eeefac71 100644
--- a/README.md
+++ b/README.md
@@ -4,6 +4,7 @@ If you need the readme for a released version of the gem please find it below:
 
 | Version  | Release Date | Readme                                                   |
 |----------|--------------|----------------------------------------------------------|
+| 1.4.7    | Mar 18, 2021 | https://github.com/oauth-xx/oauth2/blob/v1.4.7/README.md |
 | 1.4.6    | Mar 18, 2021 | https://github.com/oauth-xx/oauth2/blob/v1.4.6/README.md |
 | 1.4.5    | Mar 18, 2021 | https://github.com/oauth-xx/oauth2/blob/v1.4.5/README.md |
 | 1.4.4    | Feb 12, 2020 | https://github.com/oauth-xx/oauth2/blob/v1.4.4/README.md |

From bd7cf62f7d92abb6d4cfd3db608bc0147dcb31cf Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Thu, 18 Mar 2021 21:52:15 -0600
Subject: [PATCH 050/163] Release 1.4.7 prep

---
 oauth2.gemspec | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/oauth2.gemspec b/oauth2.gemspec
index 86a825c7..90ad0b7f 100644
--- a/oauth2.gemspec
+++ b/oauth2.gemspec
@@ -32,10 +32,9 @@ Gem::Specification.new do |spec|
 
   spec.require_paths = %w[lib]
   spec.bindir        = 'exe'
-  spec.executables   = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
-  spec.files         = `git ls-files -z`.split("\x0").reject do |f|
-    f.match(%r{^(bin|test|spec|features)/})
-  end
+  spec.files = Dir['lib/**/*', 'LICENSE', 'README.md', 'CHANGELOG.md', 'CODE_OF_CONDUCT.md']
+  spec.test_files = Dir['spec/**/*']
+  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
 
   spec.add_development_dependency 'addressable', '~> 2.3'
   spec.add_development_dependency 'backports', '~> 3.11'

From 6b438460a28930199d00f371d529e09b88296e05 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Thu, 18 Mar 2021 21:58:18 -0600
Subject: [PATCH 051/163] Travis.com

---
 README.md | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/README.md b/README.md
index eeefac71..73069edd 100644
--- a/README.md
+++ b/README.md
@@ -22,7 +22,7 @@ If you need the readme for a released version of the gem please find it below:
 [![Gem Version](http://img.shields.io/gem/v/oauth2.svg)][gem]
 [![Total Downloads](https://img.shields.io/gem/dt/oauth2.svg)][gem]
 [![Downloads Today](https://img.shields.io/gem/rt/oauth2.svg)][gem]
-[![Build Status](https://travis-ci.org/oauth-xx/oauth2.svg?branch=1-4-stable)][travis]
+[![Build Status](https://travis-ci.com/oauth-xx/oauth2.svg?branch=1-4-stable)][travis]
 [![Build Status](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Factions-badge.atrox.dev%2Foauth-xx%2Foauth2%2Fbadge&style=flat)][github-actions]
 [![Test Coverage](https://api.codeclimate.com/v1/badges/688c612528ff90a46955/test_coverage)][codeclimate-coverage]
 [![Maintainability](https://api.codeclimate.com/v1/badges/688c612528ff90a46955/maintainability)][codeclimate-maintainability]
@@ -33,7 +33,7 @@ If you need the readme for a released version of the gem please find it below:
 [![Documentation](http://inch-ci.org/github/oauth-xx/oauth2.png)][inch-ci]
 
 [gem]: https://rubygems.org/gems/oauth2
-[travis]: http://travis-ci.org/oauth-xx/oauth2
+[travis]: http://travis-ci.com/oauth-xx/oauth2
 [github-actions]: https://actions-badge.atrox.dev/oauth-xx/oauth2/goto
 [coveralls]: https://coveralls.io/r/oauth-xx/oauth2
 [codeclimate-maintainability]: https://codeclimate.com/github/oauth-xx/oauth2/maintainability

From 919cdd85e608c253b1552de827ddd76eebdf9452 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Fri, 19 Mar 2021 11:21:40 +0700
Subject: [PATCH 052/163] Pend specs on Ruby 1.9 that fail on OpenSSL changes
 (#543)

* Green the build for Ruby 1.9

* Add reason

* Add rspec-pending_for

* Only load coveralls for Ruby >= 2.7

* Linting

* More specificity
---
 oauth2.gemspec                | 1 -
 spec/helper.rb                | 1 +
 spec/oauth2/mac_token_spec.rb | 3 +++
 3 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/oauth2.gemspec b/oauth2.gemspec
index 90ad0b7f..d6226f1b 100644
--- a/oauth2.gemspec
+++ b/oauth2.gemspec
@@ -39,7 +39,6 @@ Gem::Specification.new do |spec|
   spec.add_development_dependency 'addressable', '~> 2.3'
   spec.add_development_dependency 'backports', '~> 3.11'
   spec.add_development_dependency 'bundler', '>= 1.16'
-  spec.add_development_dependency 'coveralls', '~> 0.8'
   spec.add_development_dependency 'rake', '~> 12.3'
   spec.add_development_dependency 'rdoc', ['>= 5.0', '< 7']
   spec.add_development_dependency 'rspec', '~> 3.0'
diff --git a/spec/helper.rb b/spec/helper.rb
index 8b64d420..26c3b775 100644
--- a/spec/helper.rb
+++ b/spec/helper.rb
@@ -20,6 +20,7 @@
 require 'addressable/uri'
 require 'rspec'
 require 'rspec/stubbed_env'
+require 'rspec/pending_for'
 require 'silent_stream'
 
 RSpec.configure do |config|
diff --git a/spec/oauth2/mac_token_spec.rb b/spec/oauth2/mac_token_spec.rb
index 0685350f..b358a95a 100644
--- a/spec/oauth2/mac_token_spec.rb
+++ b/spec/oauth2/mac_token_spec.rb
@@ -24,15 +24,18 @@
     end
 
     it 'defaults algorithm to hmac-sha-256' do
+      pending_for(:engine => 'ruby', :versions => '1.9.3', :reason => "Ruby 1.9's OpenSSL uses instance of OpenSSL::Digest")
       expect(subject.algorithm).to be_instance_of(OpenSSL::Digest::SHA256)
     end
 
     it 'handles hmac-sha-256' do
+      pending_for(:engine => 'ruby', :versions => '1.9.3', :reason => "Ruby 1.9's OpenSSL uses instance of OpenSSL::Digest")
       mac = described_class.new(client, token, 'abc123', :algorithm => 'hmac-sha-256')
       expect(mac.algorithm).to be_instance_of(OpenSSL::Digest::SHA256)
     end
 
     it 'handles hmac-sha-1' do
+      pending_for(:engine => 'ruby', :versions => '1.9.3', :reason => "Ruby 1.9's OpenSSL uses instance of OpenSSL::Digest")
       mac = described_class.new(client, token, 'abc123', :algorithm => 'hmac-sha-1')
       expect(mac.algorithm).to be_instance_of(OpenSSL::Digest::SHA1)
     end

From ea46006c44801867347fa9215521e39cf0e85310 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Thu, 18 Mar 2021 22:24:01 -0600
Subject: [PATCH 053/163] Update LICENSE years [ci-skip]

---
 LICENSE | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/LICENSE b/LICENSE
index 6dda5ca1..96eb4e8f 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,7 +1,7 @@
 MIT License
 
 Copyright (c) 2011 - 2013 Michael Bleigh and Intridea, Inc.
-Copyright (c) 2017 - 2018 oauth-xx organization, https://github.com/oauth-xx
+Copyright (c) 2017 - 2021 oauth-xx organization, https://github.com/oauth-xx
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal

From a508681c0da715d4076667f82635011719c0f432 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Fri, 19 Mar 2021 18:54:13 -0600
Subject: [PATCH 054/163] More specs

---
 spec/oauth2/client_spec.rb | 25 ++++++++++++++++++++++++-
 1 file changed, 24 insertions(+), 1 deletion(-)

diff --git a/spec/oauth2/client_spec.rb b/spec/oauth2/client_spec.rb
index 583ea12f..f26ad537 100644
--- a/spec/oauth2/client_spec.rb
+++ b/spec/oauth2/client_spec.rb
@@ -403,10 +403,11 @@
     describe ':raise_errors flag' do
       let(:options) { {} }
       let(:token_response) { nil }
+      let(:post_args) { [] }
 
       let(:client) do
         stubbed_client(options.merge(:raise_errors => raise_errors)) do |stub|
-          stub.post('/oauth/token') do
+          stub.post('/oauth/token', *post_args) do
             # stub 200 response so that we're testing the get_token handling of :raise_errors flag not request
             [200, {'Content-Type' => 'application/json'}, token_response]
           end
@@ -430,6 +431,28 @@
           end
         end
 
+        context 'when the request body has an access token' do
+          let(:token_response) { MultiJson.encode('access_token' => 'the-token') }
+          it 'returns the parsed :access_token from body' do
+            token = client.get_token({})
+            expect(token).to be_a OAuth2::AccessToken
+            expect(token.token).to eq('the-token')
+          end
+
+          context 'when :auth_scheme => :request_body' do
+            context 'when arbitrary params are present' do
+              let(:post_args) { ['arbitrary' => 'parameter', 'client_id' => 'abc', 'client_secret' => 'def'] }
+              let(:options) { {:auth_scheme => :request_body} }
+
+              it 'does not affect access token'  do
+                token = client.get_token(*post_args)
+                expect(token).to be_a OAuth2::AccessToken
+                expect(token.token).to eq('the-token')
+              end
+            end
+          end
+        end
+
         context 'when extract_access_token raises an exception' do
           let(:options) do
             {

From b57d57db7539c52c8ae6358a4615bbe508d19237 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Mon, 8 Nov 2021 00:44:31 -0700
Subject: [PATCH 055/163] Fix CHANGELOG for 1.4.5 release

---
 CHANGELOG.md | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index ee308fb8..114f99c5 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -17,6 +17,8 @@ All notable changes to this project will be documented in this file.
 
 - [#535](https://github.com/oauth-xx/oauth2/pull/535) - Compatibility with range of supported Ruby OpenSSL versions, Rubocop updates, Github Actions (@pboling)
 - [#518](https://github.com/oauth-xx/oauth2/pull/518) - Add extract_access_token option to OAuth2::Client (@jonspalmer)
+- [#507](https://github.com/oauth-xx/oauth2/pull/507) - Fix camel case content type, response keys (@anvox)
+- [#500](https://github.com/oauth-xx/oauth2/pull/500) - Fix YARD documentation formatting (@olleolleolle)
 
 ## [1.4.4] - 2020-02-12
 

From 6e4d401606642da5e9f6a215fea668129105096a Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Mon, 8 Nov 2021 00:51:14 -0700
Subject: [PATCH 056/163] Link to change sets for each release

---
 CHANGELOG.md | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 114f99c5..accda0cc 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -169,4 +169,8 @@ All notable changes to this project will be documented in this file.
 [1.4.1]: https://github.com/oauth-xx/oauth2/compare/v1.4.0...v1.4.1
 [1.4.2]: https://github.com/oauth-xx/oauth2/compare/v1.4.1...v1.4.2
 [1.4.3]: https://github.com/oauth-xx/oauth2/compare/v1.4.2...v1.4.3
+[1.4.4]: https://github.com/oauth-xx/oauth2/compare/v1.4.3...v1.4.4
+[1.4.5]: https://github.com/oauth-xx/oauth2/compare/v1.4.4...v1.4.5
+[1.4.6]: https://github.com/oauth-xx/oauth2/compare/v1.4.5...v1.4.6
+[1.4.7]: https://github.com/oauth-xx/oauth2/compare/v1.4.6...v1.4.7
 [unreleased]: https://github.com/oauth-xx/oauth2/compare/v1.4.1...HEAD

From dc0b4bb90b6eabe08edab67935c366736b2b0b91 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Mon, 8 Nov 2021 00:56:24 -0700
Subject: [PATCH 057/163] Sync release dates with Rubygems

---
 CHANGELOG.md | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index accda0cc..4cdc524a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,11 +3,11 @@ All notable changes to this project will be documented in this file.
 
 ## unreleased
 
-## [1.4.7] - 2021-03-18
+## [1.4.7] - 2021-03-19
 
 - [#541](https://github.com/oauth-xx/oauth2/pull/541) - Backport fix to expires_at handling [#533](https://github.com/oauth-xx/oauth2/pull/533) to 1-4-stable branch. (@dobon)
 
-## [1.4.6] - 2021-03-18
+## [1.4.6] - 2021-03-19
 
 - [#540](https://github.com/oauth-xx/oauth2/pull/540) - Add VERSION constant (@pboling)
 - [#537](https://github.com/oauth-xx/oauth2/pull/537) - Fix crash in OAuth2::Client#get_token (@anderscarling)

From 70d3974dc504acbb257fd1bd57a6de28e59bc33c Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Wed, 16 Feb 2022 02:52:39 +0700
Subject: [PATCH 058/163] =?UTF-8?q?=F0=9F=94=A5=20Kill=20more=20old=20Rubi?=
 =?UTF-8?q?es=20with=202.x=20release?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 README.md | 22 ++++++++++++----------
 1 file changed, 12 insertions(+), 10 deletions(-)

diff --git a/README.md b/README.md
index 73069edd..b3ec8503 100644
--- a/README.md
+++ b/README.md
@@ -164,24 +164,26 @@ implementations:
 * Ruby 2.0.0
   - [JRuby 9.0][jruby-9.0] (targets MRI v2.0)
 * Ruby 2.1
+* Ruby 2.2
+* Ruby 2.3
+  - [JRuby 9.1][jruby-9.1] (targets MRI v2.3)
+* Ruby 2.4
+
+[jruby-1.7]: https://www.jruby.org/2017/05/11/jruby-1-7-27.html
+[jruby-9.0]: https://www.jruby.org/2016/01/26/jruby-9-0-5-0.html
+[jruby-9.1]: https://www.jruby.org/2017/05/16/jruby-9-1-9-0.html
 
 ---
 
 ### Rubies with continued support past Oauth2 2.x
 
-* Ruby 2.2 - Support ends with version 2.x series
-* Ruby 2.3 - Support ends with version 3.x series
-  - [JRuby 9.1][jruby-9.1] (targets MRI v2.3)
-* Ruby 2.4 - Support ends with version 4.x series
-* Ruby 2.5 - Support ends with version 5.x series
+* Ruby 2.5 - Support ends with version 3.x series
   - [JRuby 9.2][jruby-9.2] (targets MRI v2.5)
   - [truffleruby][truffleruby] (targets MRI 2.5)
-* Ruby 2.6 - Support ends with version 6.x series
-* Ruby 2.7 - Support ends with version 7.x series
+* Ruby 2.6 - Support ends with version 3.x series?
+* Ruby 2.7 - Support ends with version 4.x series?
+* Ruby 3.0 - Support ends with version 5.x series?
 
-[jruby-1.7]: https://www.jruby.org/2017/05/11/jruby-1-7-27.html
-[jruby-9.0]: https://www.jruby.org/2016/01/26/jruby-9-0-5-0.html
-[jruby-9.1]: https://www.jruby.org/2017/05/16/jruby-9-1-9-0.html
 [jruby-9.2]: https://www.jruby.org/2018/05/24/jruby-9-2-0-0.html
 [truffleruby]: https://github.com/oracle/truffleruby
 

From 20fc34c9261c437e0d2c572cc10ff2a80a46b222 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Wed, 16 Feb 2022 05:34:47 +0700
Subject: [PATCH 059/163] =?UTF-8?q?=E2=9C=A8=20Add=20FUNDING.yml?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 .github/FUNDING.yml | 13 +++++++++++++
 1 file changed, 13 insertions(+)
 create mode 100644 .github/FUNDING.yml

diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
new file mode 100644
index 00000000..e21342e5
--- /dev/null
+++ b/.github/FUNDING.yml
@@ -0,0 +1,13 @@
+# These are supported funding model platforms
+
+github: [pboling] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
+patreon: galtzo # Replace with a single Patreon username
+open_collective: # Replace with a single Open Collective username
+ko_fi: pboling # Replace with a single Ko-fi username
+tidelift: rubygems/oauth2 # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
+community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
+liberapay: pboling # Replace with a single Liberapay username
+issuehunt: pboling # Replace with a single IssueHunt username
+otechie: # Replace with a single Otechie username
+lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
+custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']

From c2d434d312f08a88f1008dfb6021b1743c69bbc5 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Wed, 16 Feb 2022 08:49:15 +0700
Subject: [PATCH 060/163] =?UTF-8?q?=F0=9F=94=92=EF=B8=8F=20Require=20MFA?=
 =?UTF-8?q?=20to=20push=20gems?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 oauth2.gemspec | 1 +
 1 file changed, 1 insertion(+)

diff --git a/oauth2.gemspec b/oauth2.gemspec
index d6226f1b..ecf73185 100644
--- a/oauth2.gemspec
+++ b/oauth2.gemspec
@@ -28,6 +28,7 @@ Gem::Specification.new do |spec|
     'documentation_uri' => "https://www.rubydoc.info/gems/oauth2/#{spec.version}",
     'source_code_uri' => "https://github.com/oauth-xx/oauth2/tree/v#{spec.version}",
     'wiki_uri' => 'https://github.com/oauth-xx/oauth2/wiki',
+    "rubygems_mfa_required" => "true"
   }
 
   spec.require_paths = %w[lib]

From 36ac842c044d34915099fd3741fda329c7809be6 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Wed, 16 Feb 2022 08:51:33 +0700
Subject: [PATCH 061/163] =?UTF-8?q?=E2=9C=A8=20Add=20Danger?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 .github/workflows/danger.yml | 36 +++++++++++++++++++++++++
 Dangerfile                   | 15 +++++++++++
 Gemfile                      | 51 ++++++++++++++++++++----------------
 3 files changed, 79 insertions(+), 23 deletions(-)
 create mode 100644 .github/workflows/danger.yml
 create mode 100644 Dangerfile

diff --git a/.github/workflows/danger.yml b/.github/workflows/danger.yml
new file mode 100644
index 00000000..437c5d77
--- /dev/null
+++ b/.github/workflows/danger.yml
@@ -0,0 +1,36 @@
+name: What's up Danger?
+
+on:
+  pull_request:
+    branches:
+      - 'main'
+      - 'master'
+      - '*-stable'
+
+jobs:
+  danger:
+    runs-on: ubuntu-latest
+    if: github.event_name  == 'pull_request' # if only run pull request when multiple trigger workflow
+    strategy:
+      fail-fast: false
+      matrix:
+        ruby:
+          - 2.7
+    steps:
+      - name: Checkout
+        uses: actions/checkout@v2
+      - name: Install cURL Headers
+        run: sudo apt-get install libcurl4-openssl-dev
+      - name: Setup Ruby & Bundle
+        uses: ruby/setup-ruby@v1
+        with:
+          ruby-version: ${{ matrix.ruby }}
+          bundler-cache: true
+      - uses: MeilCli/danger-action@v5
+        with:
+          plugins_file: 'Gemfile'
+          install_path: 'vendor/bundle'
+          danger_file: 'Dangerfile'
+          danger_id: 'danger-pr'
+        env:
+          DANGER_GITHUB_API_TOKEN: ${{ secrets.DANGER_GITHUB_API_TOKEN }}
diff --git a/Dangerfile b/Dangerfile
new file mode 100644
index 00000000..41c4b546
--- /dev/null
+++ b/Dangerfile
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+# Ideas...
+# 1. Check for hashtags in PR title, and disallow changes to changelog?
+#   e.g. github.pr_title.include? "#trivial"
+
+# Make it more obvious that a PR is a work in progress and shouldn't be merged yet
+warn("PR is classed as Work in Progress") if github.pr_title.include? "[WIP]"
+
+# Warn when there is a big PR
+warn("Big PR") if git.lines_of_code > 500
+
+# Don't let testing shortcuts get into master by accident
+raise("fdescribe left in tests") if `grep -r fdescribe specs/ `.length > 1
+raise("fit left in tests") if `grep -r fit specs/ `.length > 1
diff --git a/Gemfile b/Gemfile
index 4657b438..45295bdb 100644
--- a/Gemfile
+++ b/Gemfile
@@ -10,7 +10,34 @@ gem 'faraday', ['>= 0.8', '< 2.0'], :platforms => [:jruby_18, :ruby_18]
 gem 'jwt', '< 1.5.2', :platforms => [:jruby_18, :ruby_18]
 gem 'rake', '< 11.0'
 
-ruby_version = Gem::Version.new(RUBY_VERSION)
+platforms :mri do
+  ruby_version = Gem::Version.new(RUBY_VERSION)
+  minimum_version = ->(version) { ruby_version >= Gem::Version.new(version) && RUBY_ENGINE == "ruby" }
+  linting = minimum_version.call("2.7")
+  coverage = minimum_version.call("2.7")
+  debug = minimum_version.call("2.4")
+  if linting
+    gem "danger", "~> 8.4"
+    gem "rubocop", "~> 1.22"
+    gem "rubocop-md", "~> 1.0"
+    gem "rubocop-packaging", "~> 0.5"
+    gem "rubocop-performance", "~> 1.11"
+    gem "rubocop-rake", "~> 0.6"
+    gem "rubocop-rspec"
+    gem "rubocop-thread_safety", "~> 0.4"
+  end
+  if coverage
+    gem 'coveralls'
+    gem "simplecov", "~> 0.21"
+    gem "simplecov-cobertura", "~> 2.1"
+  end
+  if debug
+    # No need to run byebug / pry on earlier versions
+    gem 'byebug'
+    gem 'pry'
+    gem 'pry-byebug'
+  end
+end
 
 ### deps for documentation and rdoc.info
 group :documentation do
@@ -20,28 +47,6 @@ group :documentation do
   gem 'yard', :require => false
 end
 
-group :development, :test do
-  if ruby_version >= Gem::Version.new('2.4')
-    # No need to run byebug / pry on earlier versions
-    gem 'byebug', :platform => :mri
-    gem 'pry', :platform => :mri
-    gem 'pry-byebug', :platform => :mri
-  end
-
-  if ruby_version >= Gem::Version.new('2.7')
-    # No need to run rubocop or simplecov on earlier versions
-    gem 'rubocop', '~> 1.9', :platform => :mri
-    gem 'rubocop-md', :platform => :mri
-    gem 'rubocop-packaging', :platform => :mri
-    gem 'rubocop-performance', :platform => :mri
-    gem 'rubocop-rake', :platform => :mri
-    gem 'rubocop-rspec', :platform => :mri
-
-    gem 'coveralls'
-    gem 'simplecov', :platform => :mri
-  end
-end
-
 group :test do
   gem 'addressable', '~> 2.3.8'
   gem 'backports'

From 863aca3bf03a7c3f311055f3270be770a2b56bae Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Wed, 16 Feb 2022 08:52:21 +0700
Subject: [PATCH 062/163] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Split=20tests=20in?=
 =?UTF-8?q?to=20supported=20and=20unsupported=20sets?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 .github/workflows/{test.yml => supported.yml} | 18 ++++----
 .github/workflows/unsupported.yml             | 44 +++++++++++++++++++
 2 files changed, 52 insertions(+), 10 deletions(-)
 rename .github/workflows/{test.yml => supported.yml} (85%)
 create mode 100644 .github/workflows/unsupported.yml

diff --git a/.github/workflows/test.yml b/.github/workflows/supported.yml
similarity index 85%
rename from .github/workflows/test.yml
rename to .github/workflows/supported.yml
index 9d0352ab..d9cc0f3c 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/supported.yml
@@ -7,6 +7,7 @@ on:
       - 'master'
       - '*-maintenance'
       - '*-dev'
+      - '*-stable'
     tags:
       - '!*' # Do not execute on tags
   pull_request:
@@ -21,14 +22,10 @@ jobs:
       fail-fast: false
       matrix:
         ruby:
-          - 3.0.0
+          - 3.1
+          - 3.0
           - 2.7
           - 2.6
-          - 2.5
-          - 2.4
-          - 2.3
-          - 2.2
-          - 2.1
     runs-on: ubuntu-20.04
     continue-on-error: ${{ matrix.allow_failure || endsWith(matrix.ruby, 'head') }}
     steps:
@@ -37,15 +34,16 @@ jobs:
         if: matrix.ruby == '2.7' && github.event_name != 'pull_request'
         with:
           cc_test_reporter_id: ${{ secrets.CC_TEST_REPORTER_ID }}
-      - uses: actions/checkout@v2
-      - name: Setup Ruby
+      - name: Checkout
+        uses: actions/checkout@v2
+      - name: Install cURL Headers
+        run: sudo apt-get install libcurl4-openssl-dev
+      - name: Setup Ruby & Bundle
         uses: ruby/setup-ruby@v1
         with:
           bundler: ${{ matrix.bundler || 2 }}
           bundler-cache: true
           ruby-version: ${{ matrix.ruby }}
-      - name: Install dependencies
-        run: bundle install --jobs 3 --retry 3 --binstubs --standalone
       - name: CodeClimate Pre-build Notification
         run: cc-test-reporter before-build
         if: matrix.ruby == '2.7' && github.event_name != 'pull_request'
diff --git a/.github/workflows/unsupported.yml b/.github/workflows/unsupported.yml
new file mode 100644
index 00000000..033f6651
--- /dev/null
+++ b/.github/workflows/unsupported.yml
@@ -0,0 +1,44 @@
+name: Unit Tests
+
+on:
+  push:
+    branches:
+      - 'main'
+      - 'master'
+      - '*-maintenance'
+      - '*-dev'
+      - '*-stable'
+    tags:
+      - '!*' # Do not execute on tags
+  pull_request:
+    branches:
+      - '*'
+
+jobs:
+  test:
+    name: Specs - Ruby ${{ matrix.ruby }} ${{ matrix.name_extra || '' }}
+    if: "!contains(github.event.commits[0].message, '[ci skip]') && !contains(github.event.commits[0].message, '[skip ci]')"
+    strategy:
+      fail-fast: false
+      matrix:
+        ruby:
+          - 2.5
+          - 2.4
+          - 2.3
+          - 2.2
+          - 2.1
+    runs-on: ubuntu-20.04
+    continue-on-error: ${{ matrix.allow_failure || endsWith(matrix.ruby, 'head') }}
+    steps:
+      - name: Checkout
+        uses: actions/checkout@v2
+      - name: Install cURL Headers
+        run: sudo apt-get install libcurl4-openssl-dev
+      - name: Setup Ruby & Bundle
+        uses: ruby/setup-ruby@v1
+        with:
+          bundler: ${{ matrix.bundler || 2 }}
+          bundler-cache: true
+          ruby-version: ${{ matrix.ruby }}
+      - name: Run tests
+        run: bundle exec rake test

From f9507e5ba241c0c59eeac6cf2da27507e75cbcec Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Wed, 16 Feb 2022 08:53:09 +0700
Subject: [PATCH 063/163] =?UTF-8?q?=E2=AC=86=EF=B8=8F=20Style=20checks=20w?=
 =?UTF-8?q?ill=20run=20on=20ubuntu-latest=20as=20a=20canary?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 .github/workflows/style.yml | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/.github/workflows/style.yml b/.github/workflows/style.yml
index fd211ace..539b3576 100644
--- a/.github/workflows/style.yml
+++ b/.github/workflows/style.yml
@@ -7,6 +7,7 @@ on:
       - 'master'
       - '*-maintenance'
       - '*-dev'
+      - '*-stable'
     tags:
       - '!*' # Do not execute on tags
   pull_request:
@@ -22,16 +23,16 @@ jobs:
       matrix:
         ruby:
           - 2.7
-    runs-on: ubuntu-20.04
+    runs-on: ubuntu-latest
     steps:
       - name: Checkout
         uses: actions/checkout@v2
-      - name: Setup Ruby
+      - name: Install cURL Headers
+        run: sudo apt-get install libcurl4-openssl-dev
+      - name: Setup Ruby & Bundle
         uses: ruby/setup-ruby@v1
         with:
           ruby-version: ${{ matrix.ruby }}
           bundler-cache: true
-      - name: Install dependencies
-        run: bundle install --jobs 3 --retry 3
       - name: Run Rubocop
-        run: bundle exec rubocop -DESP
\ No newline at end of file
+        run: bundle exec rubocop -DESP

From f332dd6a79aa4f5009f48e0d20974a647af5e7c2 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Wed, 16 Feb 2022 08:53:44 +0700
Subject: [PATCH 064/163] =?UTF-8?q?=E2=9C=A8=20Add=20Github's=20CodeQL?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 .github/workflows/codeql-analysis.yml | 70 +++++++++++++++++++++++++++
 1 file changed, 70 insertions(+)
 create mode 100644 .github/workflows/codeql-analysis.yml

diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml
new file mode 100644
index 00000000..5832ebea
--- /dev/null
+++ b/.github/workflows/codeql-analysis.yml
@@ -0,0 +1,70 @@
+# For most projects, this workflow file will not need changing; you simply need
+# to commit it to your repository.
+#
+# You may wish to alter this file to override the set of languages analyzed,
+# or to provide custom queries or build logic.
+#
+# ******** NOTE ********
+# We have attempted to detect the languages in your repository. Please check
+# the `language` matrix defined below to confirm you have the correct set of
+# supported CodeQL languages.
+#
+name: "CodeQL"
+
+on:
+  push:
+    branches: [ master, main, "*-stable" ]
+  pull_request:
+    # The branches below must be a subset of the branches above
+    branches: [ master, main, "*-stable" ]
+  schedule:
+    - cron: '35 1 * * 5'
+
+jobs:
+  analyze:
+    name: Analyze
+    runs-on: ubuntu-latest
+    permissions:
+      actions: read
+      contents: read
+      security-events: write
+
+    strategy:
+      fail-fast: false
+      matrix:
+        language: [ 'ruby' ]
+        # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
+        # Learn more about CodeQL language support at https://git.io/codeql-language-support
+
+    steps:
+    - name: Checkout repository
+      uses: actions/checkout@v2
+
+    # Initializes the CodeQL tools for scanning.
+    - name: Initialize CodeQL
+      uses: github/codeql-action/init@v1
+      with:
+        languages: ${{ matrix.language }}
+        # If you wish to specify custom queries, you can do so here or in a config file.
+        # By default, queries listed here will override any specified in a config file.
+        # Prefix the list here with "+" to use these queries and those in the config file.
+        # queries: ./path/to/local/query, your-org/your-repo/queries@main
+
+    # Autobuild attempts to build any compiled languages  (C/C++, C#, or Java).
+    # If this step fails, then you should remove it and run the build manually (see below)
+    - name: Autobuild
+      uses: github/codeql-action/autobuild@v1
+
+    # ℹ️ Command-line programs to run using the OS shell.
+    # 📚 https://git.io/JvXDl
+
+    # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
+    #    and modify them (or add more) to build your code if your project
+    #    uses a compiled language
+
+    #- run: |
+    #   make bootstrap
+    #   make release
+
+    - name: Perform CodeQL Analysis
+      uses: github/codeql-action/analyze@v1

From 526abbe45ad2e29667c7dd3e733ca595b5de22a5 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Thu, 17 Feb 2022 06:27:00 +0700
Subject: [PATCH 065/163] =?UTF-8?q?=F0=9F=91=B7=20Working=20on=20build=20m?=
 =?UTF-8?q?atrix?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 .github/workflows/supported.yml   | 52 ++++++++++++++++++++++++++-----
 .github/workflows/unsupported.yml | 40 ++++++++++++++++++------
 Gemfile                           |  1 +
 README.md                         | 17 +++++-----
 4 files changed, 85 insertions(+), 25 deletions(-)

diff --git a/.github/workflows/supported.yml b/.github/workflows/supported.yml
index d9cc0f3c..cca117a7 100644
--- a/.github/workflows/supported.yml
+++ b/.github/workflows/supported.yml
@@ -1,4 +1,4 @@
-name: Unit Tests
+name: Supported Ruby Unit Tests
 
 on:
   push:
@@ -13,6 +13,14 @@ on:
   pull_request:
     branches:
       - '*'
+  # Allow manually triggering the workflow.
+  workflow_dispatch:
+
+# Cancels all previous workflow runs for the same branch that have not yet completed.
+concurrency:
+  # The concurrency group contains the workflow name and the branch name.
+  group: ${{ github.workflow }}-${{ github.ref }}
+  cancel-in-progress: true
 
 jobs:
   test:
@@ -21,13 +29,28 @@ jobs:
     strategy:
       fail-fast: false
       matrix:
+        rubygems:
+          - latest
+        bundler:
+          - latest
         ruby:
-          - 3.1
-          - 3.0
-          - 2.7
-          - 2.6
+          - ruby-head
+          - truffleruby-head
+          - truffleruby
+          - jruby-head
+          - jruby
+          - "3.1"
+          - "3.0"
+          - "2.7"
+        include:
+          # Includes a new variable allow_failure with a value of false
+          #   for the matrix legs matching rubygems: latest, which is all of them.
+          # This is here for parity with the unsupported.yml
+          - rubygems: latest
+            allow_failures: false
+
     runs-on: ubuntu-20.04
-    continue-on-error: ${{ matrix.allow_failure || endsWith(matrix.ruby, 'head') }}
+    continue-on-error: ${{ matrix.allow_failures || endsWith(matrix.ruby, 'head') }}
     steps:
       - uses: amancevice/setup-code-climate@v0
         name: CodeClimate Install
@@ -41,9 +64,10 @@ jobs:
       - name: Setup Ruby & Bundle
         uses: ruby/setup-ruby@v1
         with:
-          bundler: ${{ matrix.bundler || 2 }}
-          bundler-cache: true
           ruby-version: ${{ matrix.ruby }}
+          rubygems: ${{ matrix.rubygems }}
+          bundler: ${{ matrix.bundler }}
+          bundler-cache: true
       - name: CodeClimate Pre-build Notification
         run: cc-test-reporter before-build
         if: matrix.ruby == '2.7' && github.event_name != 'pull_request'
@@ -54,3 +78,15 @@ jobs:
         run: cc-test-reporter after-build
         if: matrix.ruby == '2.7' && github.event_name != 'pull_request' && always()
         continue-on-error: ${{ matrix.allow_failures != 'false' }}
+
+  # Github doesn't support a real allow_failure directive, and if continue-on-error is ever true,
+  #   it seems the workflow may still succeed?
+  #   ref: https://github.com/actions/toolkit/issues/399#issuecomment-1034689649
+  conclusion:
+    runs-on: ubuntu-latest
+    needs: test
+    if: always()
+
+    steps:
+      - if: steps.test.outcome != 'success'
+        run: exit 1
diff --git a/.github/workflows/unsupported.yml b/.github/workflows/unsupported.yml
index 033f6651..f27712f9 100644
--- a/.github/workflows/unsupported.yml
+++ b/.github/workflows/unsupported.yml
@@ -1,4 +1,4 @@
-name: Unit Tests
+name: Unsupported Ruby Unit Tests
 
 on:
   push:
@@ -13,6 +13,14 @@ on:
   pull_request:
     branches:
       - '*'
+  # Allow manually triggering the workflow.
+  workflow_dispatch:
+
+# Cancels all previous workflow runs for the same branch that have not yet completed.
+concurrency:
+  # The concurrency group contains the workflow name and the branch name.
+  group: ${{ github.workflow }}-${{ github.ref }}
+  cancel-in-progress: true
 
 jobs:
   test:
@@ -21,14 +29,27 @@ jobs:
     strategy:
       fail-fast: false
       matrix:
+        rubygems:
+          - latest
+        bundler:
+          - latest
         ruby:
-          - 2.5
-          - 2.4
-          - 2.3
-          - 2.2
-          - 2.1
+          - "2.6"
+          - "2.5"
+          - "2.4"
+          - "2.3"
+          - "2.2"
+          - "2.1"
+        include:
+          # Includes a new variable allow_failure with a value of true
+          #   for the matrix legs matching rubygems: latest, which is all of them.
+          # This is a hack. Combined with continue-on-error it should allow us
+          #   to have a workflow with allowed failure
+          - rubygems: latest
+            allow_failures: true
+
     runs-on: ubuntu-20.04
-    continue-on-error: ${{ matrix.allow_failure || endsWith(matrix.ruby, 'head') }}
+    continue-on-error: ${{ matrix.allow_failures || endsWith(matrix.ruby, 'head') }}
     steps:
       - name: Checkout
         uses: actions/checkout@v2
@@ -37,8 +58,9 @@ jobs:
       - name: Setup Ruby & Bundle
         uses: ruby/setup-ruby@v1
         with:
-          bundler: ${{ matrix.bundler || 2 }}
-          bundler-cache: true
           ruby-version: ${{ matrix.ruby }}
+          rubygems: ${{ matrix.rubygems }}
+          bundler: ${{ matrix.bundler }}
+          bundler-cache: true
       - name: Run tests
         run: bundle exec rake test
diff --git a/Gemfile b/Gemfile
index 45295bdb..856d62f9 100644
--- a/Gemfile
+++ b/Gemfile
@@ -9,6 +9,7 @@ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
 gem 'faraday', ['>= 0.8', '< 2.0'], :platforms => [:jruby_18, :ruby_18]
 gem 'jwt', '< 1.5.2', :platforms => [:jruby_18, :ruby_18]
 gem 'rake', '< 11.0'
+gem "overcommit"
 
 platforms :mri do
   ruby_version = Gem::Version.new(RUBY_VERSION)
diff --git a/README.md b/README.md
index b3ec8503..0756540f 100644
--- a/README.md
+++ b/README.md
@@ -168,24 +168,25 @@ implementations:
 * Ruby 2.3
   - [JRuby 9.1][jruby-9.1] (targets MRI v2.3)
 * Ruby 2.4
+* Ruby 2.5 - Support ends with version 3.x series
+  - [JRuby 9.2][jruby-9.2] (targets MRI v2.5)
+  - [truffleruby][truffleruby] (targets MRI 2.5)
+* Ruby 2.6 - Support ends with version 3.x series?
 
+[truffleruby]: https://github.com/oracle/truffleruby
 [jruby-1.7]: https://www.jruby.org/2017/05/11/jruby-1-7-27.html
 [jruby-9.0]: https://www.jruby.org/2016/01/26/jruby-9-0-5-0.html
 [jruby-9.1]: https://www.jruby.org/2017/05/16/jruby-9-1-9-0.html
+[jruby-9.2]: https://www.jruby.org/2018/05/24/jruby-9-2-0-0.html
 
 ---
 
 ### Rubies with continued support past Oauth2 2.x
 
-* Ruby 2.5 - Support ends with version 3.x series
-  - [JRuby 9.2][jruby-9.2] (targets MRI v2.5)
-  - [truffleruby][truffleruby] (targets MRI 2.5)
-* Ruby 2.6 - Support ends with version 3.x series?
-* Ruby 2.7 - Support ends with version 4.x series?
-* Ruby 3.0 - Support ends with version 5.x series?
+* Ruby 2.7
+* Ruby 3.0
+* Ruby 3.1
 
-[jruby-9.2]: https://www.jruby.org/2018/05/24/jruby-9-2-0-0.html
-[truffleruby]: https://github.com/oracle/truffleruby
 
 If something doesn't work on one of these interpreters, it's a bug.
 

From 6e6f11307104e94cbc1ae09cb9548b895b92f06a Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Thu, 17 Feb 2022 06:30:01 +0700
Subject: [PATCH 066/163] =?UTF-8?q?=F0=9F=9A=A8=20Fixing=20lint=20issues?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 .rubocop_rspec.yml                            |  3 ++
 Dangerfile                                    |  8 ++---
 Gemfile                                       | 30 ++++++++--------
 lib/oauth2/error.rb                           |  2 +-
 lib/oauth2/mac_token.rb                       | 34 +++++++++----------
 oauth2.gemspec                                |  2 +-
 spec/oauth2/client_spec.rb                    |  3 +-
 .../strategy/client_credentials_spec.rb       |  2 +-
 8 files changed, 43 insertions(+), 41 deletions(-)

diff --git a/.rubocop_rspec.yml b/.rubocop_rspec.yml
index 347777dc..48ad1a31 100644
--- a/.rubocop_rspec.yml
+++ b/.rubocop_rspec.yml
@@ -24,3 +24,6 @@ RSpec/NestedGroups:
   
 RSpec/ExpectInHook:
   Enabled: false
+
+RSpec/MultipleMemoizedHelpers:
+  Enabled: false
diff --git a/Dangerfile b/Dangerfile
index 41c4b546..518ea63a 100644
--- a/Dangerfile
+++ b/Dangerfile
@@ -5,11 +5,11 @@
 #   e.g. github.pr_title.include? "#trivial"
 
 # Make it more obvious that a PR is a work in progress and shouldn't be merged yet
-warn("PR is classed as Work in Progress") if github.pr_title.include? "[WIP]"
+warn('PR is classed as Work in Progress') if github.pr_title.include? '[WIP]'
 
 # Warn when there is a big PR
-warn("Big PR") if git.lines_of_code > 500
+warn('Big PR') if git.lines_of_code > 500
 
 # Don't let testing shortcuts get into master by accident
-raise("fdescribe left in tests") if `grep -r fdescribe specs/ `.length > 1
-raise("fit left in tests") if `grep -r fit specs/ `.length > 1
+raise('fdescribe left in tests') if `grep -r fdescribe specs/ `.length > 1
+raise('fit left in tests') if `grep -r fit specs/ `.length > 1
diff --git a/Gemfile b/Gemfile
index 856d62f9..b13526c0 100644
--- a/Gemfile
+++ b/Gemfile
@@ -8,29 +8,29 @@ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
 
 gem 'faraday', ['>= 0.8', '< 2.0'], :platforms => [:jruby_18, :ruby_18]
 gem 'jwt', '< 1.5.2', :platforms => [:jruby_18, :ruby_18]
+gem 'overcommit'
 gem 'rake', '< 11.0'
-gem "overcommit"
 
 platforms :mri do
   ruby_version = Gem::Version.new(RUBY_VERSION)
-  minimum_version = ->(version) { ruby_version >= Gem::Version.new(version) && RUBY_ENGINE == "ruby" }
-  linting = minimum_version.call("2.7")
-  coverage = minimum_version.call("2.7")
-  debug = minimum_version.call("2.4")
+  minimum_version = ->(version) { ruby_version >= Gem::Version.new(version) && RUBY_ENGINE == 'ruby' }
+  linting = minimum_version.call('2.7')
+  coverage = minimum_version.call('2.7')
+  debug = minimum_version.call('2.4')
   if linting
-    gem "danger", "~> 8.4"
-    gem "rubocop", "~> 1.22"
-    gem "rubocop-md", "~> 1.0"
-    gem "rubocop-packaging", "~> 0.5"
-    gem "rubocop-performance", "~> 1.11"
-    gem "rubocop-rake", "~> 0.6"
-    gem "rubocop-rspec"
-    gem "rubocop-thread_safety", "~> 0.4"
+    gem 'danger', '~> 8.4'
+    gem 'rubocop', '~> 1.22'
+    gem 'rubocop-md', '~> 1.0'
+    gem 'rubocop-packaging', '~> 0.5'
+    gem 'rubocop-performance', '~> 1.11'
+    gem 'rubocop-rake', '~> 0.6'
+    gem 'rubocop-rspec'
+    gem 'rubocop-thread_safety', '~> 0.4'
   end
   if coverage
     gem 'coveralls'
-    gem "simplecov", "~> 0.21"
-    gem "simplecov-cobertura", "~> 2.1"
+    gem 'simplecov', '~> 0.21'
+    gem 'simplecov-cobertura', '~> 2.1'
   end
   if debug
     # No need to run byebug / pry on earlier versions
diff --git a/lib/oauth2/error.rb b/lib/oauth2/error.rb
index c2618a18..58e91dc9 100644
--- a/lib/oauth2/error.rb
+++ b/lib/oauth2/error.rb
@@ -23,7 +23,7 @@ def initialize(response)
     def error_message(response_body, opts = {})
       message = []
 
-      opts[:error_description] && message << opts[:error_description]
+      opts[:error_description] && (message << opts[:error_description])
 
       error_message = if opts[:error_description] && opts[:error_description].respond_to?(:encoding)
                         script_encoding = opts[:error_description].encoding
diff --git a/lib/oauth2/mac_token.rb b/lib/oauth2/mac_token.rb
index 99c6f5ec..36e95a2f 100644
--- a/lib/oauth2/mac_token.rb
+++ b/lib/oauth2/mac_token.rb
@@ -95,24 +95,22 @@ def signature(timestamp, nonce, verb, uri)
     #
     # @param [String] alg the algorithm to use (one of 'hmac-sha-1', 'hmac-sha-256')
     def algorithm=(alg)
-      @algorithm = begin
-        case alg.to_s
-        when 'hmac-sha-1'
-          begin
-            OpenSSL::Digest('SHA1').new
-          rescue StandardError
-            OpenSSL::Digest.new('SHA1')
-          end
-        when 'hmac-sha-256'
-          begin
-            OpenSSL::Digest('SHA256').new
-          rescue StandardError
-            OpenSSL::Digest.new('SHA256')
-          end
-        else
-          raise(ArgumentError, 'Unsupported algorithm')
-        end
-      end
+      @algorithm = case alg.to_s
+                   when 'hmac-sha-1'
+                     begin
+                       OpenSSL::Digest('SHA1').new
+                     rescue StandardError
+                       OpenSSL::Digest.new('SHA1')
+                     end
+                   when 'hmac-sha-256'
+                     begin
+                       OpenSSL::Digest('SHA256').new
+                     rescue StandardError
+                       OpenSSL::Digest.new('SHA256')
+                     end
+                   else
+                     raise(ArgumentError, 'Unsupported algorithm')
+                   end
     end
 
   private
diff --git a/oauth2.gemspec b/oauth2.gemspec
index ecf73185..ea621b4c 100644
--- a/oauth2.gemspec
+++ b/oauth2.gemspec
@@ -28,7 +28,7 @@ Gem::Specification.new do |spec|
     'documentation_uri' => "https://www.rubydoc.info/gems/oauth2/#{spec.version}",
     'source_code_uri' => "https://github.com/oauth-xx/oauth2/tree/v#{spec.version}",
     'wiki_uri' => 'https://github.com/oauth-xx/oauth2/wiki',
-    "rubygems_mfa_required" => "true"
+    'rubygems_mfa_required' => 'true',
   }
 
   spec.require_paths = %w[lib]
diff --git a/spec/oauth2/client_spec.rb b/spec/oauth2/client_spec.rb
index f26ad537..e713f257 100644
--- a/spec/oauth2/client_spec.rb
+++ b/spec/oauth2/client_spec.rb
@@ -433,6 +433,7 @@
 
         context 'when the request body has an access token' do
           let(:token_response) { MultiJson.encode('access_token' => 'the-token') }
+
           it 'returns the parsed :access_token from body' do
             token = client.get_token({})
             expect(token).to be_a OAuth2::AccessToken
@@ -444,7 +445,7 @@
               let(:post_args) { ['arbitrary' => 'parameter', 'client_id' => 'abc', 'client_secret' => 'def'] }
               let(:options) { {:auth_scheme => :request_body} }
 
-              it 'does not affect access token'  do
+              it 'does not affect access token' do
                 token = client.get_token(*post_args)
                 expect(token).to be_a OAuth2::AccessToken
                 expect(token.token).to eq('the-token')
diff --git a/spec/oauth2/strategy/client_credentials_spec.rb b/spec/oauth2/strategy/client_credentials_spec.rb
index 4f91bfd5..1c440c9b 100644
--- a/spec/oauth2/strategy/client_credentials_spec.rb
+++ b/spec/oauth2/strategy/client_credentials_spec.rb
@@ -9,7 +9,7 @@
       builder.adapter :test do |stub|
         stub.post('/oauth/token', 'grant_type' => 'client_credentials') do |env|
           client_id, client_secret = Base64.decode64(env[:request_headers]['Authorization'].split(' ', 2)[1]).split(':', 2)
-          client_id == 'abc' && client_secret == 'def' || raise(Faraday::Adapter::Test::Stubs::NotFound)
+          (client_id == 'abc' && client_secret == 'def') || raise(Faraday::Adapter::Test::Stubs::NotFound)
           case @mode
           when 'formencoded'
             [200, {'Content-Type' => 'application/x-www-form-urlencoded'}, kvform_token]

From 38535b8ee6764c1d0a4e7e1e2ce59688c1175b7e Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Thu, 17 Feb 2022 06:45:47 +0700
Subject: [PATCH 067/163] =?UTF-8?q?=F0=9F=92=9A=20Properly=20handle=20test?=
 =?UTF-8?q?ing=20for=20MRI=20Ruby?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 Gemfile        | 2 +-
 spec/helper.rb | 7 +++++--
 2 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/Gemfile b/Gemfile
index b13526c0..e92a1dfa 100644
--- a/Gemfile
+++ b/Gemfile
@@ -16,7 +16,7 @@ platforms :mri do
   minimum_version = ->(version) { ruby_version >= Gem::Version.new(version) && RUBY_ENGINE == 'ruby' }
   linting = minimum_version.call('2.7')
   coverage = minimum_version.call('2.7')
-  debug = minimum_version.call('2.4')
+  debug = minimum_version.call('2.5')
   if linting
     gem 'danger', '~> 8.4'
     gem 'rubocop', '~> 1.22'
diff --git a/spec/helper.rb b/spec/helper.rb
index 26c3b775..026e113d 100644
--- a/spec/helper.rb
+++ b/spec/helper.rb
@@ -1,8 +1,11 @@
 DEBUG = ENV['DEBUG'] == 'true'
 
 ruby_version = Gem::Version.new(RUBY_VERSION)
+minimum_version = ->(version) { ruby_version >= Gem::Version.new(version) && RUBY_ENGINE == 'ruby' }
+coverage = minimum_version.call('2.7')
+debug = minimum_version.call('2.5')
 
-if ruby_version >= Gem::Version.new('2.7')
+if coverage
   require 'simplecov'
   require 'coveralls'
 
@@ -14,7 +17,7 @@
   end
 end
 
-require 'byebug' if DEBUG && ruby_version >= Gem::Version.new('2.4')
+require 'byebug' if debug
 
 require 'oauth2'
 require 'addressable/uri'

From 7b4a2fd66be993084d8d42ddb5aae641bda81398 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Thu, 17 Feb 2022 07:00:09 +0700
Subject: [PATCH 068/163] =?UTF-8?q?=F0=9F=94=A5=20Remove=20coveralls=20gem?=
 =?UTF-8?q?=20and=20config?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 Gemfile        |  4 ++--
 spec/helper.rb | 16 +++++++++++++---
 2 files changed, 15 insertions(+), 5 deletions(-)

diff --git a/Gemfile b/Gemfile
index e92a1dfa..04b892cb 100644
--- a/Gemfile
+++ b/Gemfile
@@ -28,9 +28,9 @@ platforms :mri do
     gem 'rubocop-thread_safety', '~> 0.4'
   end
   if coverage
-    gem 'coveralls'
     gem 'simplecov', '~> 0.21'
-    gem 'simplecov-cobertura', '~> 2.1'
+    gem 'simplecov-lcov', '~> 0.8'
+    # gem 'simplecov-cobertura' # XML for Jenkins
   end
   if debug
     # No need to run byebug / pry on earlier versions
diff --git a/spec/helper.rb b/spec/helper.rb
index 026e113d..a4da1eca 100644
--- a/spec/helper.rb
+++ b/spec/helper.rb
@@ -7,11 +7,21 @@
 
 if coverage
   require 'simplecov'
-  require 'coveralls'
-
-  SimpleCov.formatters = [SimpleCov::Formatter::HTMLFormatter, Coveralls::SimpleCov::Formatter]
 
   SimpleCov.start do
+    if ENV['CI']
+      require 'simplecov-lcov'
+
+      SimpleCov::Formatter::LcovFormatter.config do |c|
+        c.report_with_single_file = true
+        c.single_report_path = 'coverage/lcov.info'
+      end
+
+      SimpleCov.formatters = [SimpleCov::Formatter::LcovFormatter, SimpleCov::Formatter::HTMLFormatter]
+    else
+      formatter SimpleCov::Formatter::HTMLFormatter
+    end
+
     add_filter '/spec'
     minimum_coverage(95)
   end

From 353b34f30cf5a05fc4b8b816cff67904c73c4089 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Thu, 17 Feb 2022 07:18:02 +0700
Subject: [PATCH 069/163] =?UTF-8?q?=F0=9F=92=9A=20ruby-head=20is=20not=20w?=
 =?UTF-8?q?orking=20on=20Github=20Actions?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

- so allow it to fail

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 .github/workflows/supported.yml   | 1 -
 .github/workflows/unsupported.yml | 1 +
 2 files changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/supported.yml b/.github/workflows/supported.yml
index cca117a7..1f05264a 100644
--- a/.github/workflows/supported.yml
+++ b/.github/workflows/supported.yml
@@ -34,7 +34,6 @@ jobs:
         bundler:
           - latest
         ruby:
-          - ruby-head
           - truffleruby-head
           - truffleruby
           - jruby-head
diff --git a/.github/workflows/unsupported.yml b/.github/workflows/unsupported.yml
index f27712f9..60d1e853 100644
--- a/.github/workflows/unsupported.yml
+++ b/.github/workflows/unsupported.yml
@@ -34,6 +34,7 @@ jobs:
         bundler:
           - latest
         ruby:
+          - ruby-head
           - "2.6"
           - "2.5"
           - "2.4"

From 9c6bb454205aec338d5f3ed78f4f25b2f5a7d4cf Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Thu, 17 Feb 2022 07:29:36 +0700
Subject: [PATCH 070/163] =?UTF-8?q?=F0=9F=92=9A=20Line=20up=20success=20an?=
 =?UTF-8?q?d=20failure?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 .github/workflows/supported.yml   | 14 +++++++++-----
 .github/workflows/unsupported.yml | 14 ++++++++++----
 2 files changed, 19 insertions(+), 9 deletions(-)

diff --git a/.github/workflows/supported.yml b/.github/workflows/supported.yml
index 1f05264a..ad2c5e6c 100644
--- a/.github/workflows/supported.yml
+++ b/.github/workflows/supported.yml
@@ -42,14 +42,18 @@ jobs:
           - "3.0"
           - "2.7"
         include:
-          # Includes a new variable allow_failure with a value of false
+          # Includes a new variable experimental with a value of false
           #   for the matrix legs matching rubygems: latest, which is all of them.
           # This is here for parity with the unsupported.yml
+          # This is a hack. Combined with conclusion job it should allow us
+          #   to have a workflow which runs to completion with allowed failure (e.g. for *-head builds),
+          #   while also failing the build if there are *any* failures at all.
+          # This is the "supported" build matrix, so only the "head" builds are experimental here.
           - rubygems: latest
-            allow_failures: false
+            experimental: false
 
     runs-on: ubuntu-20.04
-    continue-on-error: ${{ matrix.allow_failures || endsWith(matrix.ruby, 'head') }}
+    continue-on-error: ${{ matrix.experimental || endsWith(matrix.ruby, 'head') }}
     steps:
       - uses: amancevice/setup-code-climate@v0
         name: CodeClimate Install
@@ -70,13 +74,13 @@ jobs:
       - name: CodeClimate Pre-build Notification
         run: cc-test-reporter before-build
         if: matrix.ruby == '2.7' && github.event_name != 'pull_request'
-        continue-on-error: ${{ matrix.allow_failures != 'false' }}
+        continue-on-error: ${{ matrix.experimental != 'false' }}
       - name: Run tests
         run: bundle exec rake test
       - name: CodeClimate Post-build Notification
         run: cc-test-reporter after-build
         if: matrix.ruby == '2.7' && github.event_name != 'pull_request' && always()
-        continue-on-error: ${{ matrix.allow_failures != 'false' }}
+        continue-on-error: ${{ matrix.experimental != 'false' }}
 
   # Github doesn't support a real allow_failure directive, and if continue-on-error is ever true,
   #   it seems the workflow may still succeed?
diff --git a/.github/workflows/unsupported.yml b/.github/workflows/unsupported.yml
index 60d1e853..9238090f 100644
--- a/.github/workflows/unsupported.yml
+++ b/.github/workflows/unsupported.yml
@@ -42,15 +42,21 @@ jobs:
           - "2.2"
           - "2.1"
         include:
-          # Includes a new variable allow_failure with a value of true
+          # Includes a new variable experimental with a value of true
           #   for the matrix legs matching rubygems: latest, which is all of them.
           # This is a hack. Combined with continue-on-error it should allow us
           #   to have a workflow with allowed failure
-          - rubygems: latest
-            allow_failures: true
+          # This is the "unsupported" build matrix, so only many builds are experimental here.
+          # Even so, we do want to "support" some of the EOL rubies in the 1.4.x series on a marginal basis.
+          - ruby: ruby-head
+            experimental: true
+          - ruby: "2.1"
+            experimental: true
+          - ruby: "2.2"
+            experimental: true
 
     runs-on: ubuntu-20.04
-    continue-on-error: ${{ matrix.allow_failures || endsWith(matrix.ruby, 'head') }}
+    continue-on-error: ${{ matrix.experimental || endsWith(matrix.ruby, 'head') }}
     steps:
       - name: Checkout
         uses: actions/checkout@v2

From 5db8bea0a43384d1b98fca2d4714aba84eaeda9a Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Thu, 17 Feb 2022 07:38:13 +0700
Subject: [PATCH 071/163] =?UTF-8?q?=F0=9F=9A=A7=20Trying=20to=20understand?=
 =?UTF-8?q?=20steps.test.outcome?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 .github/workflows/supported.yml | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/.github/workflows/supported.yml b/.github/workflows/supported.yml
index ad2c5e6c..0016c1e7 100644
--- a/.github/workflows/supported.yml
+++ b/.github/workflows/supported.yml
@@ -91,5 +91,8 @@ jobs:
     if: always()
 
     steps:
-      - if: steps.test.outcome != 'success'
-        run: exit 1
+      - name: How did it go?
+      run:
+        - echo "${{ steps.test.outcome }} != 'success'"
+        - exit 1
+      if: steps.test.outcome != 'success'

From 00781e448a4ad29b8acf02df37125d03cfc551ab Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Thu, 17 Feb 2022 07:39:51 +0700
Subject: [PATCH 072/163] =?UTF-8?q?=F0=9F=9A=A7=20Trying=20to=20understand?=
 =?UTF-8?q?=20steps.test.outcome?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 .github/workflows/supported.yml | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/.github/workflows/supported.yml b/.github/workflows/supported.yml
index 0016c1e7..35a193bd 100644
--- a/.github/workflows/supported.yml
+++ b/.github/workflows/supported.yml
@@ -92,7 +92,7 @@ jobs:
 
     steps:
       - name: How did it go?
-      run:
-        - echo "${{ steps.test.outcome }} != 'success'"
-        - exit 1
+      run: |
+        echo "${{ steps.test.outcome }} != 'success'"
+        exit 1
       if: steps.test.outcome != 'success'

From f0a2e1c19b3a9a0a66d0edce0fa8ef6a6c823bb2 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Thu, 17 Feb 2022 07:41:36 +0700
Subject: [PATCH 073/163] =?UTF-8?q?=F0=9F=92=9A=20Fixing=20Github=20Action?=
 =?UTF-8?q?s?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 .github/workflows/supported.yml | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/.github/workflows/supported.yml b/.github/workflows/supported.yml
index 35a193bd..dec2138f 100644
--- a/.github/workflows/supported.yml
+++ b/.github/workflows/supported.yml
@@ -91,8 +91,7 @@ jobs:
     if: always()
 
     steps:
-      - name: How did it go?
-      run: |
-        echo "${{ steps.test.outcome }} != 'success'"
-        exit 1
-      if: steps.test.outcome != 'success'
+      - if: steps.test.outcome != 'success'
+        run: |
+          echo "${{ steps.test.outcome }} != 'success'"
+          exit 1

From 7ca88ea81ede5e8e3fe4ed97f64fca57a4376e07 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Thu, 17 Feb 2022 07:47:48 +0700
Subject: [PATCH 074/163] =?UTF-8?q?=F0=9F=92=9A=20Stop=20using=20undocumen?=
 =?UTF-8?q?ted=20feature=20of=20Github=20Actions?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 .github/workflows/supported.yml   | 19 ++-----------------
 .github/workflows/unsupported.yml |  2 --
 2 files changed, 2 insertions(+), 19 deletions(-)

diff --git a/.github/workflows/supported.yml b/.github/workflows/supported.yml
index dec2138f..f68eade3 100644
--- a/.github/workflows/supported.yml
+++ b/.github/workflows/supported.yml
@@ -45,9 +45,8 @@ jobs:
           # Includes a new variable experimental with a value of false
           #   for the matrix legs matching rubygems: latest, which is all of them.
           # This is here for parity with the unsupported.yml
-          # This is a hack. Combined with conclusion job it should allow us
-          #   to have a workflow which runs to completion with allowed failure (e.g. for *-head builds),
-          #   while also failing the build if there are *any* failures at all.
+          # This is a hack. Combined with continue-on-error it should allow us
+          #   to have a workflow with allowed failure.
           # This is the "supported" build matrix, so only the "head" builds are experimental here.
           - rubygems: latest
             experimental: false
@@ -81,17 +80,3 @@ jobs:
         run: cc-test-reporter after-build
         if: matrix.ruby == '2.7' && github.event_name != 'pull_request' && always()
         continue-on-error: ${{ matrix.experimental != 'false' }}
-
-  # Github doesn't support a real allow_failure directive, and if continue-on-error is ever true,
-  #   it seems the workflow may still succeed?
-  #   ref: https://github.com/actions/toolkit/issues/399#issuecomment-1034689649
-  conclusion:
-    runs-on: ubuntu-latest
-    needs: test
-    if: always()
-
-    steps:
-      - if: steps.test.outcome != 'success'
-        run: |
-          echo "${{ steps.test.outcome }} != 'success'"
-          exit 1
diff --git a/.github/workflows/unsupported.yml b/.github/workflows/unsupported.yml
index 9238090f..8206a092 100644
--- a/.github/workflows/unsupported.yml
+++ b/.github/workflows/unsupported.yml
@@ -44,8 +44,6 @@ jobs:
         include:
           # Includes a new variable experimental with a value of true
           #   for the matrix legs matching rubygems: latest, which is all of them.
-          # This is a hack. Combined with continue-on-error it should allow us
-          #   to have a workflow with allowed failure
           # This is the "unsupported" build matrix, so only many builds are experimental here.
           # Even so, we do want to "support" some of the EOL rubies in the 1.4.x series on a marginal basis.
           - ruby: ruby-head

From 64eb46af3d1240c471be08f31b052577ac14b655 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Thu, 17 Feb 2022 08:16:15 +0700
Subject: [PATCH 075/163] =?UTF-8?q?=F0=9F=92=9A=20Split=20coverage=20into?=
 =?UTF-8?q?=20separate=20workflow?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 .github/workflows/coverage.yml  | 104 ++++++++++++++++++++++++++++++++
 .github/workflows/supported.yml |  15 +----
 .travis.yml                     |  75 -----------------------
 Gemfile                         |  38 +++++-------
 spec/helper.rb                  |   9 ++-
 5 files changed, 127 insertions(+), 114 deletions(-)
 create mode 100644 .github/workflows/coverage.yml
 delete mode 100644 .travis.yml

diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml
new file mode 100644
index 00000000..a1f2c6b0
--- /dev/null
+++ b/.github/workflows/coverage.yml
@@ -0,0 +1,104 @@
+name: Code Coverage
+
+on:
+  push:
+    branches:
+      - 'main'
+      - 'master'
+      - '*-maintenance'
+      - '*-dev'
+      - '*-stable'
+    tags:
+      - '!*' # Do not execute on tags
+  pull_request:
+    branches:
+      - '*'
+  # Allow manually triggering the workflow.
+  workflow_dispatch:
+
+# Cancels all previous workflow runs for the same branch that have not yet completed.
+concurrency:
+  # The concurrency group contains the workflow name and the branch name.
+  group: ${{ github.workflow }}-${{ github.ref }}
+  cancel-in-progress: true
+
+jobs:
+  test:
+    name: Specs with Coverage - Ruby ${{ matrix.ruby }} ${{ matrix.name_extra || '' }}
+    if: "!contains(github.event.commits[0].message, '[ci skip]') && !contains(github.event.commits[0].message, '[skip ci]')"
+    strategy:
+      fail-fast: false
+      matrix:
+        rubygems:
+          - latest
+        bundler:
+          - latest
+        ruby:
+          - "2.7"
+        include:
+          # Includes a new variable experimental with a value of false
+          #   for the matrix legs matching rubygems: latest, which is all of them.
+          # This is here for parity with the unsupported.yml
+          # This is a hack. Combined with continue-on-error it should allow us
+          #   to have a workflow with allowed failure.
+          # This is the "supported" build matrix, so only the "head" builds are experimental here.
+          - rubygems: latest
+            experimental: false
+
+    runs-on: ubuntu-20.04
+    continue-on-error: ${{ matrix.experimental || endsWith(matrix.ruby, 'head') }}
+    steps:
+      - uses: amancevice/setup-code-climate@v0
+        name: CodeClimate Install
+        if: matrix.ruby == '2.7' && github.event_name != 'pull_request'
+        with:
+          cc_test_reporter_id: ${{ secrets.CC_TEST_REPORTER_ID }}
+      - name: Checkout
+        uses: actions/checkout@v2
+      - name: Install cURL Headers
+        run: sudo apt-get install libcurl4-openssl-dev
+      - name: Setup Ruby & Bundle
+        uses: ruby/setup-ruby@v1
+        with:
+          ruby-version: ${{ matrix.ruby }}
+          rubygems: ${{ matrix.rubygems }}
+          bundler: ${{ matrix.bundler }}
+          bundler-cache: true
+      - name: CodeClimate Pre-build Notification
+        run: cc-test-reporter before-build
+        if: matrix.ruby == '2.7' && github.event_name != 'pull_request'
+        continue-on-error: ${{ matrix.experimental != 'false' }}
+      - name: Run tests
+        run: bundle exec rake test
+      - name: CodeClimate Post-build Notification
+        run: cc-test-reporter after-build
+        if: matrix.ruby == '2.7' && github.event_name != 'pull_request' && always()
+        continue-on-error: ${{ matrix.experimental != 'false' }}
+
+      - name: Code Coverage Summary Report
+        uses: irongut/CodeCoverageSummary@v1.2.0
+        with:
+          filename: coverage.cobertura.xml
+          badge: true
+          fail_below_min: true
+          format: markdown
+          hide_branch_rate: false
+          hide_complexity: true
+          indicators: true
+          output: both
+          thresholds: '95 97'
+        continue-on-error: ${{ matrix.experimental != 'false' }}
+
+      - name: Add Coverage PR Comment
+        uses: marocchino/sticky-pull-request-comment@v2
+        if: github.event_name == 'pull_request'
+        with:
+          recreate: true
+          path: code-coverage-results.md
+        continue-on-error: ${{ matrix.experimental != 'false' }}
+
+      - name: Coveralls
+        uses: coverallsapp/github-action@master
+        with:
+          github-token: ${{ secrets.GITHUB_TOKEN }}
+        continue-on-error: ${{ matrix.experimental != 'false' }}
diff --git a/.github/workflows/supported.yml b/.github/workflows/supported.yml
index f68eade3..e30db635 100644
--- a/.github/workflows/supported.yml
+++ b/.github/workflows/supported.yml
@@ -40,7 +40,7 @@ jobs:
           - jruby
           - "3.1"
           - "3.0"
-          - "2.7"
+          # - "2.7" tested in coverage workflow
         include:
           # Includes a new variable experimental with a value of false
           #   for the matrix legs matching rubygems: latest, which is all of them.
@@ -54,11 +54,6 @@ jobs:
     runs-on: ubuntu-20.04
     continue-on-error: ${{ matrix.experimental || endsWith(matrix.ruby, 'head') }}
     steps:
-      - uses: amancevice/setup-code-climate@v0
-        name: CodeClimate Install
-        if: matrix.ruby == '2.7' && github.event_name != 'pull_request'
-        with:
-          cc_test_reporter_id: ${{ secrets.CC_TEST_REPORTER_ID }}
       - name: Checkout
         uses: actions/checkout@v2
       - name: Install cURL Headers
@@ -70,13 +65,5 @@ jobs:
           rubygems: ${{ matrix.rubygems }}
           bundler: ${{ matrix.bundler }}
           bundler-cache: true
-      - name: CodeClimate Pre-build Notification
-        run: cc-test-reporter before-build
-        if: matrix.ruby == '2.7' && github.event_name != 'pull_request'
-        continue-on-error: ${{ matrix.experimental != 'false' }}
       - name: Run tests
         run: bundle exec rake test
-      - name: CodeClimate Post-build Notification
-        run: cc-test-reporter after-build
-        if: matrix.ruby == '2.7' && github.event_name != 'pull_request' && always()
-        continue-on-error: ${{ matrix.experimental != 'false' }}
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 26059437..00000000
--- a/.travis.yml
+++ /dev/null
@@ -1,75 +0,0 @@
-before_install:
-  # rubygems 2.7.8 and greater include bundler
-  # - Ruby 2.2, and under, get RubyGems ~> 2.7.10, (includes bundler 1.17.3)
-  # - Anything else, including Ruby 2.3, and above, gets RubyGems ~> 3, and update bundler to latest
-  # - NOTE ON JRUBY: identifies as RUBY_VERSION ~> 1.9, 2.0, 2.3, or 2.5.
-  # - NOTE ON TRUFFLERUBY: identifies as RUBY_VERSION ~> 2.6
-  - |
-    rv="$(ruby -e 'STDOUT.write RUBY_VERSION')"
-    echo "Discovered Ruby Version of =====> $rv"
-    if   [ "$rv" \< "2.3" ]; then
-      gem update --system 2.7.10
-    elif   [ "$rv" \< "2.4" ]; then
-      gem update --system 2.7.10 --no-document
-    elif [ "$rv" = "2.5.3" ]; then
-      # JRUBY 9.2 Identifies as 2.5.3, and it fails to update rubygems
-      gem install --no-document bundler "bundler:>=2.0"
-    else
-      gem update --system --no-document --conservative
-      gem install --no-document bundler "bundler:>=2.0"
-    fi
-
-before_script:
-  - curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
-  - chmod +x ./cc-test-reporter
-  - ./cc-test-reporter before-build
-
-after_script:
-  - ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT
-
-bundler_args: --no-deployment --jobs 3 --retry 3
-
-cache: bundler
-
-env:
-  global:
-    - JRUBY_OPTS="$JRUBY_OPTS -Xcli.debug=true --debug"
-    - CC_TEST_REPORTER_ID=29caf9cf27d27ae609c088feb9d4ba34460f7a39251f2e8615c9a16f3075530e
-
-language: ruby
-
-matrix:
-  allow_failures:
-    - rvm: jruby-head
-    - rvm: ruby-head
-    - rvm: truffleruby
-    - rvm: jruby-9.0
-    - rvm: jruby-9.1 # jruby-9.1 often fails to download, thus failing the build.
-    - rvm: jruby-9.2 # jruby-9.2 often fails to download, thus failing the build.
-  fast_finish: true
-  include:
-#    - rvm: jruby-1.7 # targets MRI v1.9
-#      gemfile: gemfiles/jruby_1.7.gemfile
-    - rvm: 1.9
-      gemfile: gemfiles/ruby_1.9.gemfile
-    - rvm: 2.0
-      gemfile: gemfiles/ruby_2.0.gemfile
-    - rvm: jruby-9.0 # targets MRI v2.0
-      gemfile: gemfiles/jruby_9.0.gemfile
-    # DEPRECATION WARNING
-    # NOTE: Specs for Ruby 2.1 are now running with Github Actions
-    # oauth2 1.x series releases are the last to support Ruby versions above
-    # oauth2 2.x series releases will support Ruby versions below, and not above
-    # NOTE: Specs for Ruby 2.2, 2.3, 2.4, 2.5, 2.6, 2.7 & 3.0 are now running with Github Actions
-    - rvm: jruby-9.1 # targets MRI v2.3
-      gemfile: gemfiles/jruby_9.1.gemfile
-    - rvm: jruby-9.2 # targets MRI v2.5
-      gemfile: gemfiles/jruby_9.2.gemfile
-    - rvm: jruby-head
-      gemfile: gemfiles/jruby_head.gemfile
-    - rvm: ruby-head
-      gemfile: gemfiles/ruby_head.gemfile
-    - rvm: truffleruby
-      gemfile: gemfiles/truffleruby.gemfile
-
-sudo: false
diff --git a/Gemfile b/Gemfile
index 04b892cb..8a2edce2 100644
--- a/Gemfile
+++ b/Gemfile
@@ -7,9 +7,9 @@ gemspec
 git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
 
 gem 'faraday', ['>= 0.8', '< 2.0'], :platforms => [:jruby_18, :ruby_18]
-gem 'jwt', '< 1.5.2', :platforms => [:jruby_18, :ruby_18]
+gem 'jwt'
 gem 'overcommit'
-gem 'rake', '< 11.0'
+gem 'rake'
 
 platforms :mri do
   ruby_version = Gem::Version.new(RUBY_VERSION)
@@ -19,18 +19,19 @@ platforms :mri do
   debug = minimum_version.call('2.5')
   if linting
     gem 'danger', '~> 8.4'
-    gem 'rubocop', '~> 1.22'
-    gem 'rubocop-md', '~> 1.0'
-    gem 'rubocop-packaging', '~> 0.5'
-    gem 'rubocop-performance', '~> 1.11'
-    gem 'rubocop-rake', '~> 0.6'
-    gem 'rubocop-rspec'
-    gem 'rubocop-thread_safety', '~> 0.4'
+    gem 'rubocop', '~> 1.22', require: false
+    gem 'rubocop-md', '~> 1.0', require: false
+    gem 'rubocop-packaging', '~> 0.5', require: false
+    gem 'rubocop-performance', '~> 1.11', require: false
+    gem 'rubocop-rake', '~> 0.6', require: false
+    gem 'rubocop-rspec', require: false
+    gem 'rubocop-thread_safety', '~> 0.4', require: false
   end
   if coverage
-    gem 'simplecov', '~> 0.21'
-    gem 'simplecov-lcov', '~> 0.8'
-    # gem 'simplecov-cobertura' # XML for Jenkins
+    gem 'coveralls_reborn', '~> 0.23.1', require: false
+    gem 'simplecov', '~> 0.21', require: false
+    gem 'simplecov-lcov', '~> 0.8', require: false
+    gem 'simplecov-cobertura' # XML for Jenkins
   end
   if debug
     # No need to run byebug / pry on earlier versions
@@ -51,17 +52,6 @@ end
 group :test do
   gem 'addressable', '~> 2.3.8'
   gem 'backports'
-  gem 'rack', '~> 1.2', :platforms => [:jruby_18, :jruby_19, :ruby_18, :ruby_19, :ruby_20, :ruby_21]
+  gem 'rack', '~> 1.2', :platforms => [:ruby_21]
   gem 'rspec', '>= 3'
-
-  platforms :jruby_18, :ruby_18 do
-    gem 'mime-types', '~> 1.25'
-    gem 'rest-client', '~> 1.6.0'
-  end
-
-  platforms :ruby_18, :ruby_19 do
-    gem 'json', '< 2.0'
-    gem 'term-ansicolor', '< 1.4.0'
-    gem 'tins', '< 1.7'
-  end
 end
diff --git a/spec/helper.rb b/spec/helper.rb
index a4da1eca..c78930d6 100644
--- a/spec/helper.rb
+++ b/spec/helper.rb
@@ -11,13 +11,20 @@
   SimpleCov.start do
     if ENV['CI']
       require 'simplecov-lcov'
+      require 'simplecov-cobertura'
+      require 'coveralls'
 
       SimpleCov::Formatter::LcovFormatter.config do |c|
         c.report_with_single_file = true
         c.single_report_path = 'coverage/lcov.info'
       end
 
-      SimpleCov.formatters = [SimpleCov::Formatter::LcovFormatter, SimpleCov::Formatter::HTMLFormatter]
+      SimpleCov.formatters = [
+        SimpleCov::Formatter::HTMLFormatter,
+        SimpleCov::Formatter::LcovFormatter,
+        SimpleCov::Formatter::CoberturaFormatter,
+        Coveralls::SimpleCov::Formatter,
+      ]
     else
       formatter SimpleCov::Formatter::HTMLFormatter
     end

From 21017233d2b86c285b338c891d2a43741b9c7f86 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Thu, 17 Feb 2022 08:18:42 +0700
Subject: [PATCH 076/163] =?UTF-8?q?=F0=9F=92=9A=20Hash=20Rockets?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 Gemfile | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/Gemfile b/Gemfile
index 8a2edce2..c1908a68 100644
--- a/Gemfile
+++ b/Gemfile
@@ -19,19 +19,19 @@ platforms :mri do
   debug = minimum_version.call('2.5')
   if linting
     gem 'danger', '~> 8.4'
-    gem 'rubocop', '~> 1.22', require: false
-    gem 'rubocop-md', '~> 1.0', require: false
-    gem 'rubocop-packaging', '~> 0.5', require: false
-    gem 'rubocop-performance', '~> 1.11', require: false
-    gem 'rubocop-rake', '~> 0.6', require: false
-    gem 'rubocop-rspec', require: false
-    gem 'rubocop-thread_safety', '~> 0.4', require: false
+    gem 'rubocop', '~> 1.22', :require => false
+    gem 'rubocop-md', '~> 1.0', :require => false
+    gem 'rubocop-packaging', '~> 0.5', :require => false
+    gem 'rubocop-performance', '~> 1.11', :require => false
+    gem 'rubocop-rake', '~> 0.6', :require => false
+    gem 'rubocop-rspec', :require => false
+    gem 'rubocop-thread_safety', '~> 0.4', :require => false
   end
   if coverage
-    gem 'coveralls_reborn', '~> 0.23.1', require: false
-    gem 'simplecov', '~> 0.21', require: false
-    gem 'simplecov-lcov', '~> 0.8', require: false
+    gem 'coveralls_reborn', '~> 0.23.1', :require => false
+    gem 'simplecov', '~> 0.21', :require => false
     gem 'simplecov-cobertura' # XML for Jenkins
+    gem 'simplecov-lcov', '~> 0.8', :require => false
   end
   if debug
     # No need to run byebug / pry on earlier versions

From 0cbb72fb48a7b37fa48f542f87dd17ea35a8fafb Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Thu, 17 Feb 2022 08:21:36 +0700
Subject: [PATCH 077/163] =?UTF-8?q?=F0=9F=93=88=20Code=20Coverage=20PR=20C?=
 =?UTF-8?q?omments?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 .github/workflows/coverage.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml
index a1f2c6b0..50099453 100644
--- a/.github/workflows/coverage.yml
+++ b/.github/workflows/coverage.yml
@@ -78,7 +78,7 @@ jobs:
       - name: Code Coverage Summary Report
         uses: irongut/CodeCoverageSummary@v1.2.0
         with:
-          filename: coverage.cobertura.xml
+          filename: coverage.xml
           badge: true
           fail_below_min: true
           format: markdown

From 1c250d82f8139d2a2509a0559c4f32e4ad342119 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Thu, 17 Feb 2022 08:25:39 +0700
Subject: [PATCH 078/163] =?UTF-8?q?=F0=9F=9A=9A=20Code=20Coverage=20PR=20C?=
 =?UTF-8?q?omments?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 .github/workflows/coverage.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml
index 50099453..e32d346f 100644
--- a/.github/workflows/coverage.yml
+++ b/.github/workflows/coverage.yml
@@ -78,7 +78,7 @@ jobs:
       - name: Code Coverage Summary Report
         uses: irongut/CodeCoverageSummary@v1.2.0
         with:
-          filename: coverage.xml
+          filename: coverage/coverage.xml
           badge: true
           fail_below_min: true
           format: markdown

From 5e7798ac8bfdc4f3d8537d423af23be5f33ec681 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Thu, 17 Feb 2022 10:33:24 +0700
Subject: [PATCH 079/163] =?UTF-8?q?=F0=9F=9A=9A=20Code=20Coverage=20FTW?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 .github/workflows/coverage.yml | 32 ++++++++++++++++++++++----------
 1 file changed, 22 insertions(+), 10 deletions(-)

diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml
index e32d346f..76f3139e 100644
--- a/.github/workflows/coverage.yml
+++ b/.github/workflows/coverage.yml
@@ -48,15 +48,18 @@ jobs:
     runs-on: ubuntu-20.04
     continue-on-error: ${{ matrix.experimental || endsWith(matrix.ruby, 'head') }}
     steps:
+      - name: Install cURL Headers
+        run: sudo apt-get install libcurl4-openssl-dev
+
       - uses: amancevice/setup-code-climate@v0
         name: CodeClimate Install
-        if: matrix.ruby == '2.7' && github.event_name != 'pull_request'
+        if: matrix.ruby == '2.7' && github.event_name != 'pull_request' && always()
         with:
           cc_test_reporter_id: ${{ secrets.CC_TEST_REPORTER_ID }}
+
       - name: Checkout
         uses: actions/checkout@v2
-      - name: Install cURL Headers
-        run: sudo apt-get install libcurl4-openssl-dev
+
       - name: Setup Ruby & Bundle
         uses: ruby/setup-ruby@v1
         with:
@@ -64,21 +67,19 @@ jobs:
           rubygems: ${{ matrix.rubygems }}
           bundler: ${{ matrix.bundler }}
           bundler-cache: true
+
       - name: CodeClimate Pre-build Notification
         run: cc-test-reporter before-build
-        if: matrix.ruby == '2.7' && github.event_name != 'pull_request'
+        if: matrix.ruby == '2.7' && github.event_name != 'pull_request' && always()
         continue-on-error: ${{ matrix.experimental != 'false' }}
+
       - name: Run tests
         run: bundle exec rake test
-      - name: CodeClimate Post-build Notification
-        run: cc-test-reporter after-build
-        if: matrix.ruby == '2.7' && github.event_name != 'pull_request' && always()
-        continue-on-error: ${{ matrix.experimental != 'false' }}
 
       - name: Code Coverage Summary Report
         uses: irongut/CodeCoverageSummary@v1.2.0
         with:
-          filename: coverage/coverage.xml
+          filename: ./coverage/coverage.xml
           badge: true
           fail_below_min: true
           format: markdown
@@ -91,7 +92,7 @@ jobs:
 
       - name: Add Coverage PR Comment
         uses: marocchino/sticky-pull-request-comment@v2
-        if: github.event_name == 'pull_request'
+        if: matrix.ruby == '2.7' && github.event_name == 'pull_request' && always()
         with:
           recreate: true
           path: code-coverage-results.md
@@ -99,6 +100,17 @@ jobs:
 
       - name: Coveralls
         uses: coverallsapp/github-action@master
+        if: matrix.ruby == '2.7' && github.event_name != 'pull_request' && always()
         with:
           github-token: ${{ secrets.GITHUB_TOKEN }}
         continue-on-error: ${{ matrix.experimental != 'false' }}
+
+      - name: CodeCov
+        uses: codecov/codecov-action@v2
+        if: matrix.ruby == '2.7' && github.event_name != 'pull_request' && always()
+        with:
+          files: ./coverage/coverage.xml
+          flags: unittests
+          name: codecov-upload
+          fail_ci_if_error: true
+        continue-on-error: ${{ matrix.experimental != 'false' }}

From 4333b72e6312f8428da5efb18b85d95609d111a1 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Thu, 17 Feb 2022 10:43:12 +0700
Subject: [PATCH 080/163] =?UTF-8?q?=F0=9F=8D=BB=20Turn=20on=20hide=5Fbranc?=
 =?UTF-8?q?h=5Frate?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 .github/workflows/coverage.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml
index 76f3139e..b1a17deb 100644
--- a/.github/workflows/coverage.yml
+++ b/.github/workflows/coverage.yml
@@ -83,7 +83,7 @@ jobs:
           badge: true
           fail_below_min: true
           format: markdown
-          hide_branch_rate: false
+          hide_branch_rate: true
           hide_complexity: true
           indicators: true
           output: both

From c4dab4f13b0924ba0278fbea5d9e0ae147977c78 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Thu, 17 Feb 2022 10:56:47 +0700
Subject: [PATCH 081/163] =?UTF-8?q?=F0=9F=93=8C=20Relax=20pin=20for=20cove?=
 =?UTF-8?q?ralls=5Freborn?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 Gemfile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Gemfile b/Gemfile
index c1908a68..6484fe07 100644
--- a/Gemfile
+++ b/Gemfile
@@ -28,7 +28,7 @@ platforms :mri do
     gem 'rubocop-thread_safety', '~> 0.4', :require => false
   end
   if coverage
-    gem 'coveralls_reborn', '~> 0.23.1', :require => false
+    gem 'coveralls_reborn', '~> 0.23', :require => false
     gem 'simplecov', '~> 0.21', :require => false
     gem 'simplecov-cobertura' # XML for Jenkins
     gem 'simplecov-lcov', '~> 0.8', :require => false

From fee8d2f4c1ed0695e328bdbcd06e20fb0a8887e5 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Thu, 17 Feb 2022 10:58:29 +0700
Subject: [PATCH 082/163] =?UTF-8?q?=E2=9E=96=20Remove=20rdoc=20in=20favor?=
 =?UTF-8?q?=20of=20yard?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 Gemfile | 1 -
 1 file changed, 1 deletion(-)

diff --git a/Gemfile b/Gemfile
index 6484fe07..bc3497be 100644
--- a/Gemfile
+++ b/Gemfile
@@ -44,7 +44,6 @@ end
 ### deps for documentation and rdoc.info
 group :documentation do
   gem 'github-markup', :platform => :mri
-  gem 'rdoc'
   gem 'redcarpet', :platform => :mri
   gem 'yard', :require => false
 end

From d5c821aee8a7e5836f30fa855d6e1b54ad4cf699 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Thu, 17 Feb 2022 11:04:15 +0700
Subject: [PATCH 083/163] =?UTF-8?q?=F0=9F=93=8C=20Run=20coverage=20on=20ub?=
 =?UTF-8?q?untu-latest?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 .github/workflows/coverage.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml
index b1a17deb..5194c0f7 100644
--- a/.github/workflows/coverage.yml
+++ b/.github/workflows/coverage.yml
@@ -45,7 +45,7 @@ jobs:
           - rubygems: latest
             experimental: false
 
-    runs-on: ubuntu-20.04
+    runs-on: ubuntu-latest
     continue-on-error: ${{ matrix.experimental || endsWith(matrix.ruby, 'head') }}
     steps:
       - name: Install cURL Headers

From 7445afcf8dfdc5301317bf8eb3a1223ef3f8cd75 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Thu, 17 Feb 2022 11:06:49 +0700
Subject: [PATCH 084/163] =?UTF-8?q?=F0=9F=93=8C=20Run=20supported=20on=20u?=
 =?UTF-8?q?buntu-latest?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 .github/workflows/supported.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/supported.yml b/.github/workflows/supported.yml
index e30db635..62312ed4 100644
--- a/.github/workflows/supported.yml
+++ b/.github/workflows/supported.yml
@@ -51,7 +51,7 @@ jobs:
           - rubygems: latest
             experimental: false
 
-    runs-on: ubuntu-20.04
+    runs-on: ubuntu-latest
     continue-on-error: ${{ matrix.experimental || endsWith(matrix.ruby, 'head') }}
     steps:
       - name: Checkout

From 0db6294ded053b6ec4c729b24113913e1da3ad87 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Fri, 18 Feb 2022 00:50:58 +0700
Subject: [PATCH 085/163] =?UTF-8?q?=F0=9F=8F=97=EF=B8=8F=20Only=20load=20b?=
 =?UTF-8?q?yebug=20when=20DEBUG=3Dtrue?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 spec/helper.rb | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/spec/helper.rb b/spec/helper.rb
index c78930d6..cabfe9c6 100644
--- a/spec/helper.rb
+++ b/spec/helper.rb
@@ -34,7 +34,7 @@
   end
 end
 
-require 'byebug' if debug
+require 'byebug' if DEBUG && debug
 
 require 'oauth2'
 require 'addressable/uri'

From 11b8ea36c0df376f9f51cc9fc9f281c70acb047c Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Fri, 18 Feb 2022 00:49:41 +0700
Subject: [PATCH 086/163] =?UTF-8?q?=E2=9E=96=20Remove=20Danger=20(Faraday?=
 =?UTF-8?q?=20incompatibility)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

- https://github.com/danger/danger/issues/1349

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 .github/workflows/danger.yml | 3 ++-
 Gemfile                      | 4 +++-
 spec/helper.rb               | 2 +-
 3 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/.github/workflows/danger.yml b/.github/workflows/danger.yml
index 437c5d77..93812baf 100644
--- a/.github/workflows/danger.yml
+++ b/.github/workflows/danger.yml
@@ -10,7 +10,8 @@ on:
 jobs:
   danger:
     runs-on: ubuntu-latest
-    if: github.event_name  == 'pull_request' # if only run pull request when multiple trigger workflow
+    if: false
+    # if: github.event_name  == 'pull_request' # if only run pull request when multiple trigger workflow
     strategy:
       fail-fast: false
       matrix:
diff --git a/Gemfile b/Gemfile
index bc3497be..8a3e11f7 100644
--- a/Gemfile
+++ b/Gemfile
@@ -18,7 +18,9 @@ platforms :mri do
   coverage = minimum_version.call('2.7')
   debug = minimum_version.call('2.5')
   if linting
-    gem 'danger', '~> 8.4'
+    # Danger is incompatible with Faraday 2 (for now)
+    # see: https://github.com/danger/danger/issues/1349
+    # gem 'danger', '~> 8.4'
     gem 'rubocop', '~> 1.22', :require => false
     gem 'rubocop-md', '~> 1.0', :require => false
     gem 'rubocop-packaging', '~> 0.5', :require => false
diff --git a/spec/helper.rb b/spec/helper.rb
index cabfe9c6..fdbab2eb 100644
--- a/spec/helper.rb
+++ b/spec/helper.rb
@@ -9,7 +9,7 @@
   require 'simplecov'
 
   SimpleCov.start do
-    if ENV['CI']
+    if ENV['CI'] || ENV['CODECOV']
       require 'simplecov-lcov'
       require 'simplecov-cobertura'
       require 'coveralls'

From 724f55866438f9a00b8447421b86b5153b34a0b8 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Fri, 18 Feb 2022 01:43:27 +0700
Subject: [PATCH 087/163] =?UTF-8?q?=F0=9F=91=B7=20Disable=20rubocop=20Styl?=
 =?UTF-8?q?e/IfUnlessModifier=20rule?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 .rubocop.yml | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/.rubocop.yml b/.rubocop.yml
index 3c1afd65..5bccdf12 100644
--- a/.rubocop.yml
+++ b/.rubocop.yml
@@ -109,4 +109,8 @@ Style/ExpandPathArguments:
 
 # On Ruby 1.9 array.to_h isn't available, needs to be Hash[array]
 Style/HashConversion:
-  Enabled: false
\ No newline at end of file
+  Enabled: false
+
+# Turn back on once old Rubies are dropped
+Style/IfUnlessModifier:
+  Enabled: false

From 9d86d00f75261a6b2f5cf426fd1644a87dae0edf Mon Sep 17 00:00:00 2001
From: Jonathan Rochkind <jonathan@dnil.net>
Date: Thu, 17 Feb 2022 13:49:45 -0500
Subject: [PATCH 088/163] =?UTF-8?q?=F0=9F=94=80=20Support=20Faraday=202.x?=
 =?UTF-8?q?=20on=201-4-stable=20branch,=20for=20subsequent=201.x=20release?=
 =?UTF-8?q?=20(#569)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* Backport: Fix spec for support faraday 2 (#561)

Co-authored-by: Ryo Takahashi <info@ryo.gift>

* Additional changes ported back from master to allow faraday 1.x and 2.x

Co-authored-by: Ryo Takahashi <takahashi@ryo.gift>
Co-authored-by: Ryo Takahashi <info@ryo.gift>
---
 Gemfile                                |  2 +-
 lib/oauth2/client.rb                   | 11 ++++-------
 oauth2.gemspec                         |  2 +-
 spec/oauth2/client_spec.rb             |  4 ++--
 spec/oauth2/strategy/assertion_spec.rb |  3 ++-
 spec/oauth2/strategy/password_spec.rb  |  3 ++-
 6 files changed, 12 insertions(+), 13 deletions(-)

diff --git a/Gemfile b/Gemfile
index 8a3e11f7..07873599 100644
--- a/Gemfile
+++ b/Gemfile
@@ -6,7 +6,7 @@ gemspec
 
 git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
 
-gem 'faraday', ['>= 0.8', '< 2.0'], :platforms => [:jruby_18, :ruby_18]
+gem 'faraday', ['>= 0.8', '< 3.0'], :platforms => [:jruby_18, :ruby_18]
 gem 'jwt'
 gem 'overcommit'
 gem 'rake'
diff --git a/lib/oauth2/client.rb b/lib/oauth2/client.rb
index f98a9f37..3a11aa27 100644
--- a/lib/oauth2/client.rb
+++ b/lib/oauth2/client.rb
@@ -59,15 +59,12 @@ def site=(value)
 
     # The Faraday connection object
     def connection
-      @connection ||= begin
-        conn = Faraday.new(site, options[:connection_opts])
-        if options[:connection_build]
-          conn.build do |b|
-            options[:connection_build].call(b)
+      @connection ||=
+        Faraday.new(site, options[:connection_opts]) do |builder|
+          if options[:connection_build]
+            options[:connection_build].call(builder)
           end
         end
-        conn
-      end
     end
 
     # The authorize endpoint URL of the OAuth2 provider
diff --git a/oauth2.gemspec b/oauth2.gemspec
index ea621b4c..8480ac0e 100644
--- a/oauth2.gemspec
+++ b/oauth2.gemspec
@@ -5,7 +5,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
 require 'oauth2/version'
 
 Gem::Specification.new do |spec|
-  spec.add_dependency 'faraday', ['>= 0.8', '< 2.0']
+  spec.add_dependency 'faraday', ['>= 0.8', '< 3.0']
   spec.add_dependency 'jwt', ['>= 1.0', '< 3.0']
   spec.add_dependency 'multi_json', '~> 1.3'
   spec.add_dependency 'multi_xml', '~> 0.5'
diff --git a/spec/oauth2/client_spec.rb b/spec/oauth2/client_spec.rb
index e713f257..85712f58 100644
--- a/spec/oauth2/client_spec.rb
+++ b/spec/oauth2/client_spec.rb
@@ -46,7 +46,7 @@
     it 'is able to pass a block to configure the connection' do
       connection = double('connection')
       builder = double('builder')
-      allow(connection).to receive(:build).and_yield(builder)
+      allow(Faraday).to receive(:new).and_yield(builder)
       allow(Faraday::Connection).to receive(:new).and_return(connection)
 
       expect(builder).to receive(:adapter).with(:test)
@@ -517,7 +517,7 @@ def stubbed_client(params = {}, &stubs)
   context 'with SSL options' do
     subject do
       cli = described_class.new('abc', 'def', :site => 'https://api.example.com', :ssl => {:ca_file => 'foo.pem'})
-      cli.connection.build do |b|
+      cli.connection = Faraday.new(cli.site, cli.options[:connection_opts]) do |b|
         b.adapter :test
       end
       cli
diff --git a/spec/oauth2/strategy/assertion_spec.rb b/spec/oauth2/strategy/assertion_spec.rb
index 148e3e3a..ea1436e8 100644
--- a/spec/oauth2/strategy/assertion_spec.rb
+++ b/spec/oauth2/strategy/assertion_spec.rb
@@ -3,7 +3,8 @@
 
   let(:client) do
     cli = OAuth2::Client.new('abc', 'def', :site => 'http://api.example.com')
-    cli.connection.build do |b|
+    cli.connection = Faraday.new(cli.site, cli.options[:connection_opts]) do |b|
+      b.request :url_encoded
       b.adapter :test do |stub|
         stub.post('/oauth/token') do |env|
           case @mode
diff --git a/spec/oauth2/strategy/password_spec.rb b/spec/oauth2/strategy/password_spec.rb
index c8b006aa..f46c9f0f 100644
--- a/spec/oauth2/strategy/password_spec.rb
+++ b/spec/oauth2/strategy/password_spec.rb
@@ -3,7 +3,8 @@
 
   let(:client) do
     cli = OAuth2::Client.new('abc', 'def', :site => 'http://api.example.com')
-    cli.connection.build do |b|
+    cli.connection = Faraday.new(cli.site, cli.options[:connection_opts]) do |b|
+      b.request :url_encoded
       b.adapter :test do |stub|
         stub.post('/oauth/token') do |env|
           case @mode

From 8b7117f2da7e5980621a3b8d4ff243c0cfd79cbc Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Fri, 18 Feb 2022 01:54:48 +0700
Subject: [PATCH 089/163] =?UTF-8?q?=F0=9F=91=B7=20Disable=20rubocop=20Styl?=
 =?UTF-8?q?e/SafeNavigation=20rule?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 .rubocop.yml | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/.rubocop.yml b/.rubocop.yml
index 5bccdf12..58996661 100644
--- a/.rubocop.yml
+++ b/.rubocop.yml
@@ -114,3 +114,6 @@ Style/HashConversion:
 # Turn back on once old Rubies are dropped
 Style/IfUnlessModifier:
   Enabled: false
+
+Style/SafeNavigation:
+  Enabled: false

From 57c5cf816fca74bc1c84180db36accbb1c144250 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Fri, 18 Feb 2022 04:11:15 +0700
Subject: [PATCH 090/163] =?UTF-8?q?=F0=9F=93=9D=20Parity=20with=20Readme?=
 =?UTF-8?q?=20from=20master=20branch?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 README.md                              | 222 +++---
 docs/images/logo/README.txt            |  15 +
 docs/images/logo/oauth2-logo-124px.png | Bin 0 -> 13391 bytes
 docs/images/logo/ruby-logo-198px.svg   | 948 +++++++++++++++++++++++++
 4 files changed, 1105 insertions(+), 80 deletions(-)
 create mode 100644 docs/images/logo/README.txt
 create mode 100644 docs/images/logo/oauth2-logo-124px.png
 create mode 100644 docs/images/logo/ruby-logo-198px.svg

diff --git a/README.md b/README.md
index 0756540f..1bad21ca 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,39 @@
-# OAuth2
+<p align="center">
+    <a href="http://oauth.net/2/" target="_blank" rel="noopener noreferrer">
+      <img src="https://github.com/oauth-xx/oauth2/raw/master/docs/images/logo/oauth2-logo-124px.png?raw=true" alt="OAuth 2.0 Logo by Chris Messina, CC BY-SA 3.0">
+    </a>
+    <a href="https://www.ruby-lang.org/" target="_blank" rel="noopener noreferrer">
+      <img width="124px" src="https://github.com/oauth-xx/oauth2/raw/master/docs/images/logo/ruby-logo-198px.svg?raw=true" alt="Yukihiro Matsumoto, Ruby Visual Identity Team, CC BY-SA 2.5">
+    </a>
+</p>
+
+## What
+
+OAuth 2.0 is the industry-standard protocol for authorization.
+OAuth 2.0 focuses on client developer simplicity while providing specific authorization flows for web applications,
+    desktop applications, mobile phones, and living room devices.
+This is a RubyGem for implementing OAuth 2.0 clients and servers in Ruby applications.
+See the sibling `oauth` gem for OAuth 1.0 implementations in Ruby.
+
+⚠️ **_WARNING_**: You are viewing the `README` of the soon-to-be-deprecated `1-4-stable` 
+branch which for version 1.4.x releases. Version 2.0 is coming! ⚠️
 
-If you need the readme for a released version of the gem please find it below:
+---
+
+* [OAuth 2.0 Spec][oauth2-spec]
+* [OAuth 1.0 sibling gem][sibling-gem]
+* Help us reach the [2.0.0 release milestone][next-milestone] by submitting or reviewing PRs and issues.
+* Oauth2 gem is _always_ looking for additional maintainers. See [#307][maintainers-discussion].
+
+[oauth2-spec]: https://oauth.net/2/
+[sibling-gem]: https://github.com/oauth-xx/oauth-ruby
+[next-milestone]: https://github.com/oauth-xx/oauth2/milestone/1
+[maintainers-discussion]: https://github.com/oauth-xx/oauth2/issues/307
+
+## Release Documentation
+
+<details>
+  <summary>1.4.x Readmes</summary>
 
 | Version  | Release Date | Readme                                                   |
 |----------|--------------|----------------------------------------------------------|
@@ -12,17 +45,32 @@ If you need the readme for a released version of the gem please find it below:
 | 1.4.2    | Oct 1, 2019  | https://github.com/oauth-xx/oauth2/blob/v1.4.2/README.md |
 | 1.4.1    | Oct 13, 2018 | https://github.com/oauth-xx/oauth2/blob/v1.4.1/README.md |
 | 1.4.0    | Jun 9, 2017  | https://github.com/oauth-xx/oauth2/blob/v1.4.0/README.md |
+</details>
+
+<details>
+  <summary>1.3.x Readmes</summary>
+
+| Version  | Release Date | Readme                                                   |
+|----------|--------------|----------------------------------------------------------|
 | 1.3.1    | Mar 3, 2017  | https://github.com/oauth-xx/oauth2/blob/v1.3.1/README.md |
 | 1.3.0    | Dec 27, 2016 | https://github.com/oauth-xx/oauth2/blob/v1.3.0/README.md |
+</details>
+
+<details>
+  <summary>&le;= 1.2.x Readmes (2016 and before)</summary>
+
+| Version  | Release Date | Readme                                                   |
+|----------|--------------|----------------------------------------------------------|
 | 1.2.0    | Jun 30, 2016 | https://github.com/oauth-xx/oauth2/blob/v1.2.0/README.md |
 | 1.1.0    | Jan 30, 2016 | https://github.com/oauth-xx/oauth2/blob/v1.1.0/README.md |
 | 1.0.0    | May 23, 2014 | https://github.com/oauth-xx/oauth2/blob/v1.0.0/README.md |
 | < 1.0.0  | Find here    | https://github.com/oauth-xx/oauth2/tags                  |
+</details>
+
 
 [![Gem Version](http://img.shields.io/gem/v/oauth2.svg)][gem]
 [![Total Downloads](https://img.shields.io/gem/dt/oauth2.svg)][gem]
 [![Downloads Today](https://img.shields.io/gem/rt/oauth2.svg)][gem]
-[![Build Status](https://travis-ci.com/oauth-xx/oauth2.svg?branch=1-4-stable)][travis]
 [![Build Status](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Factions-badge.atrox.dev%2Foauth-xx%2Foauth2%2Fbadge&style=flat)][github-actions]
 [![Test Coverage](https://api.codeclimate.com/v1/badges/688c612528ff90a46955/test_coverage)][codeclimate-coverage]
 [![Maintainability](https://api.codeclimate.com/v1/badges/688c612528ff90a46955/maintainability)][codeclimate-maintainability]
@@ -31,9 +79,9 @@ If you need the readme for a released version of the gem please find it below:
 [![Chat](https://img.shields.io/gitter/room/oauth-xx/oauth2.svg)](https://gitter.im/oauth-xx/oauth2)
 [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)][source-license]
 [![Documentation](http://inch-ci.org/github/oauth-xx/oauth2.png)][inch-ci]
+[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Foauth-xx%2Foauth2.svg?type=shield)][fossa1]
 
 [gem]: https://rubygems.org/gems/oauth2
-[travis]: http://travis-ci.com/oauth-xx/oauth2
 [github-actions]: https://actions-badge.atrox.dev/oauth-xx/oauth2/goto
 [coveralls]: https://coveralls.io/r/oauth-xx/oauth2
 [codeclimate-maintainability]: https://codeclimate.com/github/oauth-xx/oauth2/maintainability
@@ -44,25 +92,64 @@ If you need the readme for a released version of the gem please find it below:
 [code-triage]: https://www.codetriage.com/oauth-xx/oauth2
 [fossa1]: https://app.fossa.io/projects/git%2Bgithub.com%2Foauth-xx%2Foauth2?ref=badge_shield
 
-A Ruby wrapper for the [OAuth 2.0 specification][oauth2-spec].
-
-[oauth2-spec]: https://oauth.net/2/
-
 ## Installation
 
-Add this line to your application's Gemfile:
+```shell
+gem install oauth2
+```
+
+Or inside a `Gemfile`
 
 ```ruby
 gem 'oauth2'
 ```
+And then execute in a shell:
+```shell
+bundle
+```
+
+
+## Compatibility
+
+Targeted ruby compatibility is non-EOL versions of Ruby, currently 2.7, 3.0 and
+3.1. Compatibility is further distinguished by supported and unsupported versions of Ruby.
+Ruby is limited to 1.9+ in the gemspec for the 1.4.x series and will be 2.2+ for 2.x releases (see `master` branch).
 
-And then execute:
+<details>
+  <summary>Ruby Engine Compatibility</summary>
 
-    $ bundle
+This gem is tested against MRI, JRuby, and Truffleruby.
+Each of those has varying versions that target a specific version of MRI Ruby.
+This gem should work in the just-listed Ruby engines according to the targeted MRI compatibility in the table below.
+If you would like to add support for additional engines, 
+  first make sure Github Actions supports the engine,
+  then submit a PR to the correct maintenance branch as according to the table below.
+</details>
 
-Or install it yourself as:
+| Ruby OAuth 2 Version | Maintenance Branch | Supported Officially    | Supported Unofficially | Supported Incidentally |
+|----------------------|--------------------|-------------------------|-------------------------------------------------|
+| 2.0.x (unreleased)   | `master`           | 2.7, 3.0, 3.1           | 2.6, 2.5               | 2.4, 2.3, 2.2          |
+| 1.4.x                | `1-4-stable`       | 2.5, 2.6, 2.7, 3.0, 3.1 | 2.1, 2.2, 2.3, 2.4     | 2.0, 1.9               |
+| older                | N/A                | Best of luck to you!    | Please upgrade!        |                        |
+
+NOTE: Once 2.0 is released, the 1.4 series will only receive critical bug and security updates.
+
+<details>
+  <summary>Ruby Compatibility Policy</summary>
+
+If something doesn't work on one of these interpreters, it's a bug.
 
-    $ gem install oauth2
+This library may inadvertently work (or seem to work) on other Ruby
+implementations, however support will only be provided for the versions listed
+above.
+
+If you would like this library to support another Ruby version, you may
+volunteer to be a maintainer. Being a maintainer entails making sure all tests
+run and pass on that implementation. When something breaks on your
+implementation, you will be responsible for providing patches in a timely
+fashion. If critical issues for a particular implementation exist at the time
+of a major release, support for that Ruby version may be dropped.
+</details>
 
 ## Resources
 
@@ -72,7 +159,7 @@ Or install it yourself as:
 
 [code]: https://github.com/oauth-xx/oauth2
 [issues]: https://github.com/oauth-xx/oauth2/issues
-[wiki]: https://wiki.github.com/oauth-xx/oauth2
+[wiki]: https://github.com/oauth-xx/oauth2/wiki
 
 ## Usage Examples
 
@@ -88,13 +175,38 @@ response = token.get('/api/resource', :params => {'query_foo' => 'bar'})
 response.class.name
 # => OAuth2::Response
 ```
+
+<details>
+  <summary>Debugging</summary>
+
+Set an environment variable, however you would [normally do that](https://github.com/bkeepers/dotenv).
+
+```ruby
+# will log both request and response, including bodies
+ENV['OAUTH_DEBUG'] = 'true'
+```
+
+By default, debug output will go to `$stdout`. This can be overridden when
+initializing your OAuth2::Client.
+
+```ruby
+require 'oauth2'
+client = OAuth2::Client.new(
+  'client_id',
+  'client_secret',
+  site: 'https://example.org',
+  logger: Logger.new('example.log', 'weekly')
+)
+```
+</details>
+
 ## OAuth2::Response
 
-The AccessToken methods #get, #post, #put and #delete and the generic #request
+The `AccessToken` methods `#get`, `#post`, `#put` and `#delete` and the generic `#request`
 will return an instance of the #OAuth2::Response class.
 
-This instance contains a #parsed method that will parse the response body and
-return a Hash if the Content-Type is application/x-www-form-urlencoded or if
+This instance contains a `#parsed` method that will parse the response body and
+return a Hash if the `Content-Type` is `application/x-www-form-urlencoded` or if
 the body is a JSON object.  It will return an Array if the body is a JSON
 array.  Otherwise, it will return the original body string.
 
@@ -104,27 +216,27 @@ respective methods.
 ## OAuth2::AccessToken
 
 If you have an existing Access Token for a user, you can initialize an instance
-using various class methods including the standard new, from_hash (if you have
-a hash of the values), or from_kvform (if you have an
-application/x-www-form-urlencoded encoded string of the values).
+using various class methods including the standard new, `from_hash` (if you have
+a hash of the values), or `from_kvform` (if you have an
+`application/x-www-form-urlencoded` encoded string of the values).
 
 ## OAuth2::Error
 
-On 400+ status code responses, an OAuth2::Error will be raised.  If it is a
-standard OAuth2 error response, the body will be parsed and #code and #description will contain the values provided from the error and
-error_description parameters.  The #response property of OAuth2::Error will
-always contain the OAuth2::Response instance.
+On 400+ status code responses, an `OAuth2::Error` will be raised.  If it is a
+standard OAuth2 error response, the body will be parsed and `#code` and `#description` will contain the values provided from the error and
+`error_description` parameters.  The `#response` property of `OAuth2::Error` will
+always contain the `OAuth2::Response` instance.
 
-If you do not want an error to be raised, you may use :raise_errors => false
-option on initialization of the client.  In this case the OAuth2::Response
+If you do not want an error to be raised, you may use `:raise_errors => false`
+option on initialization of the client.  In this case the `OAuth2::Response`
 instance will be returned as usual and on 400+ status code responses, the
-Response instance will contain the OAuth2::Error instance.
+Response instance will contain the `OAuth2::Error` instance.
 
 ## Authorization Grants
 
 Currently the Authorization Code, Implicit, Resource Owner Password Credentials, Client Credentials, and Assertion
 authentication grant types have helper strategy classes that simplify client
-use.  They are available via the #auth_code, #implicit, #password, #client_credentials, and #assertion methods respectively.
+use. They are available via the `#auth_code`, `#implicit`, `#password`, `#client_credentials`, and `#assertion` methods respectively.
 
 ```ruby
 auth_url = client.auth_code.authorize_url(:redirect_uri => 'http://localhost:8080/oauth/callback')
@@ -148,59 +260,9 @@ request, add a 'headers' hash under 'params':
 token = client.auth_code.get_token('code_value', :redirect_uri => 'http://localhost:8080/oauth/callback', :headers => {'Some' => 'Header'})
 ```
 
-You can always use the #request method on the OAuth2::Client instance to make
+You can always use the `#request` method on the `OAuth2::Client` instance to make
 requests for tokens for any Authentication grant type.
 
-## Supported Ruby Versions
-
-This library aims to support and is [tested against][travis] the following Ruby
-implementations:
-
-### Rubies with support ending at Oauth2 1.x
-
-* Ruby 1.9.3
-  - [JRuby 1.7][jruby-1.7] (targets MRI v1.9)
-
-* Ruby 2.0.0
-  - [JRuby 9.0][jruby-9.0] (targets MRI v2.0)
-* Ruby 2.1
-* Ruby 2.2
-* Ruby 2.3
-  - [JRuby 9.1][jruby-9.1] (targets MRI v2.3)
-* Ruby 2.4
-* Ruby 2.5 - Support ends with version 3.x series
-  - [JRuby 9.2][jruby-9.2] (targets MRI v2.5)
-  - [truffleruby][truffleruby] (targets MRI 2.5)
-* Ruby 2.6 - Support ends with version 3.x series?
-
-[truffleruby]: https://github.com/oracle/truffleruby
-[jruby-1.7]: https://www.jruby.org/2017/05/11/jruby-1-7-27.html
-[jruby-9.0]: https://www.jruby.org/2016/01/26/jruby-9-0-5-0.html
-[jruby-9.1]: https://www.jruby.org/2017/05/16/jruby-9-1-9-0.html
-[jruby-9.2]: https://www.jruby.org/2018/05/24/jruby-9-2-0-0.html
-
----
-
-### Rubies with continued support past Oauth2 2.x
-
-* Ruby 2.7
-* Ruby 3.0
-* Ruby 3.1
-
-
-If something doesn't work on one of these interpreters, it's a bug.
-
-This library may inadvertently work (or seem to work) on other Ruby
-implementations, however support will only be provided for the versions listed
-above.
-
-If you would like this library to support another Ruby version, you may
-volunteer to be a maintainer. Being a maintainer entails making sure all tests
-run and pass on that implementation. When something breaks on your
-implementation, you will be responsible for providing patches in a timely
-fashion. If critical issues for a particular implementation exist at the time
-of a major release, support for that Ruby version may be dropped.
-
 ## Versioning
 
 This library aims to adhere to [Semantic Versioning 2.0.0][semver].
@@ -238,7 +300,7 @@ spec.add_dependency 'oauth2', '~> 1.4'
 
 ## Development
 
-After checking out the repo, run `bundle install` to install dependencies. Then, run `rake spec` to run the tests.
+After checking out the repo, run `bundle install` to install dependencies. Then, run `bundle excec rake spec` to run the tests.
 
 To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
 
diff --git a/docs/images/logo/README.txt b/docs/images/logo/README.txt
new file mode 100644
index 00000000..bb405554
--- /dev/null
+++ b/docs/images/logo/README.txt
@@ -0,0 +1,15 @@
+The OAuth 2.0 Logo - oauth2-logo-124px.png (resized)
+
+https://oauth.net/about/credits/
+
+The OAuth logo was designed by Chris Messina.
+
+---
+
+The Ruby Logo - ruby-logo-124px.jpeg (resized)
+
+https://www.ruby-lang.org/en/about/logo/
+
+Yukihiro Matsumoto, Ruby Visual Identity Team, CC BY-SA 2.5
+
+https://creativecommons.org/licenses/by-sa/2.5
diff --git a/docs/images/logo/oauth2-logo-124px.png b/docs/images/logo/oauth2-logo-124px.png
new file mode 100644
index 0000000000000000000000000000000000000000..41a8d35aa834108cdfb86d5b9d8eef369367c324
GIT binary patch
diff --git a/docs/images/logo/ruby-logo-198px.svg b/docs/images/logo/ruby-logo-198px.svg
new file mode 100644
index 00000000..59cf324f
--- /dev/null
+++ b/docs/images/logo/ruby-logo-198px.svg
@@ -0,0 +1,948 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 12.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 51448)  -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   id="Layer_1"
+   width="198.13"
+   height="197.58"
+   viewBox="0 0 198.13 197.58"
+   overflow="visible"
+   enable-background="new 0 0 198.13 197.58"
+   xml:space="preserve"
+   inkscape:version="0.48.0 r9654"
+   sodipodi:docname="Logo-Ruby.svg"><metadata
+   id="metadata3320"><rdf:RDF><cc:Work
+       rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+         rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+   id="defs3489"><linearGradient
+     id="XMLID_17_-9"
+     gradientUnits="userSpaceOnUse"
+     x1="174.0737"
+     y1="215.5488"
+     x2="132.27631"
+     y2="141.7533"><stop
+       offset="0"
+       style="stop-color:#FB7655"
+       id="stop3272-4" /><stop
+       offset="0"
+       style="stop-color:#FB7655"
+       id="stop3274-5" /><stop
+       offset="0.41"
+       style="stop-color:#E42B1E"
+       id="stop3276-1" /><stop
+       offset="0.99"
+       style="stop-color:#990000"
+       id="stop3278-0" /><stop
+       offset="1"
+       style="stop-color:#990000"
+       id="stop3280-3" /></linearGradient><linearGradient
+     id="XMLID_18_-7"
+     gradientUnits="userSpaceOnUse"
+     x1="194.895"
+     y1="153.5576"
+     x2="141.0276"
+     y2="117.4093"><stop
+       offset="0"
+       style="stop-color:#871101"
+       id="stop3285-8" /><stop
+       offset="0"
+       style="stop-color:#871101"
+       id="stop3287-8" /><stop
+       offset="0.99"
+       style="stop-color:#911209"
+       id="stop3289-6" /><stop
+       offset="1"
+       style="stop-color:#911209"
+       id="stop3291-0" /></linearGradient><linearGradient
+     id="XMLID_19_-4"
+     gradientUnits="userSpaceOnUse"
+     x1="151.79539"
+     y1="217.7852"
+     x2="97.929703"
+     y2="181.638"><stop
+       offset="0"
+       style="stop-color:#871101"
+       id="stop3296-6" /><stop
+       offset="0"
+       style="stop-color:#871101"
+       id="stop3298-7" /><stop
+       offset="0.99"
+       style="stop-color:#911209"
+       id="stop3300-6" /><stop
+       offset="1"
+       style="stop-color:#911209"
+       id="stop3302-0" /></linearGradient><linearGradient
+     id="XMLID_20_-9"
+     gradientUnits="userSpaceOnUse"
+     x1="38.696301"
+     y1="127.3906"
+     x2="47.046902"
+     y2="181.66141"><stop
+       offset="0"
+       style="stop-color:#FFFFFF"
+       id="stop3307-7" /><stop
+       offset="0"
+       style="stop-color:#FFFFFF"
+       id="stop3309-5" /><stop
+       offset="0.23"
+       style="stop-color:#E57252"
+       id="stop3311-9" /><stop
+       offset="0.46"
+       style="stop-color:#DE3B20"
+       id="stop3313-7" /><stop
+       offset="0.99"
+       style="stop-color:#A60003"
+       id="stop3315-8" /><stop
+       offset="1"
+       style="stop-color:#A60003"
+       id="stop3317-5" /></linearGradient><linearGradient
+     id="XMLID_21_-3"
+     gradientUnits="userSpaceOnUse"
+     x1="96.132797"
+     y1="76.715302"
+     x2="99.209602"
+     y2="132.1021"><stop
+       offset="0"
+       style="stop-color:#FFFFFF"
+       id="stop3322-3" /><stop
+       offset="0"
+       style="stop-color:#FFFFFF"
+       id="stop3324-8" /><stop
+       offset="0.23"
+       style="stop-color:#E4714E"
+       id="stop3326-3" /><stop
+       offset="0.56"
+       style="stop-color:#BE1A0D"
+       id="stop3328-7" /><stop
+       offset="0.99"
+       style="stop-color:#A80D00"
+       id="stop3330-9" /><stop
+       offset="1"
+       style="stop-color:#A80D00"
+       id="stop3332-3" /></linearGradient><linearGradient
+     id="XMLID_22_-7"
+     gradientUnits="userSpaceOnUse"
+     x1="147.103"
+     y1="25.521"
+     x2="156.3141"
+     y2="65.216202"><stop
+       offset="0"
+       style="stop-color:#FFFFFF"
+       id="stop3337-8" /><stop
+       offset="0"
+       style="stop-color:#FFFFFF"
+       id="stop3339-7" /><stop
+       offset="0.18"
+       style="stop-color:#E46342"
+       id="stop3341-4" /><stop
+       offset="0.4"
+       style="stop-color:#C82410"
+       id="stop3343-1" /><stop
+       offset="0.99"
+       style="stop-color:#A80D00"
+       id="stop3345-9" /><stop
+       offset="1"
+       style="stop-color:#A80D00"
+       id="stop3347-0" /></linearGradient><linearGradient
+     id="XMLID_23_-9"
+     gradientUnits="userSpaceOnUse"
+     x1="118.9761"
+     y1="11.5415"
+     x2="158.66859"
+     y2="-8.3048"><stop
+       offset="0"
+       style="stop-color:#FFFFFF"
+       id="stop3352-8" /><stop
+       offset="0"
+       style="stop-color:#FFFFFF"
+       id="stop3354-8" /><stop
+       offset="0.54"
+       style="stop-color:#C81F11"
+       id="stop3356-5" /><stop
+       offset="0.99"
+       style="stop-color:#BF0905"
+       id="stop3358-8" /><stop
+       offset="1"
+       style="stop-color:#BF0905"
+       id="stop3360-4" /></linearGradient><linearGradient
+     id="XMLID_24_-3"
+     gradientUnits="userSpaceOnUse"
+     x1="3.9033"
+     y1="113.5547"
+     x2="7.1701999"
+     y2="146.2628"><stop
+       offset="0"
+       style="stop-color:#FFFFFF"
+       id="stop3365-7" /><stop
+       offset="0"
+       style="stop-color:#FFFFFF"
+       id="stop3367-1" /><stop
+       offset="0.31"
+       style="stop-color:#DE4024"
+       id="stop3369-3" /><stop
+       offset="0.99"
+       style="stop-color:#BF190B"
+       id="stop3371-8" /><stop
+       offset="1"
+       style="stop-color:#BF190B"
+       id="stop3373-0" /></linearGradient><linearGradient
+     id="XMLID_25_-9"
+     gradientUnits="userSpaceOnUse"
+     x1="-18.5557"
+     y1="155.10451"
+     x2="135.0152"
+     y2="-2.8092999"><stop
+       offset="0"
+       style="stop-color:#BD0012"
+       id="stop3380-7" /><stop
+       offset="0"
+       style="stop-color:#BD0012"
+       id="stop3382-9" /><stop
+       offset="0.07"
+       style="stop-color:#FFFFFF"
+       id="stop3384-9" /><stop
+       offset="0.17"
+       style="stop-color:#FFFFFF"
+       id="stop3386-3" /><stop
+       offset="0.27"
+       style="stop-color:#C82F1C"
+       id="stop3388-2" /><stop
+       offset="0.33"
+       style="stop-color:#820C01"
+       id="stop3390-4" /><stop
+       offset="0.46"
+       style="stop-color:#A31601"
+       id="stop3392-3" /><stop
+       offset="0.72"
+       style="stop-color:#B31301"
+       id="stop3394-7" /><stop
+       offset="0.99"
+       style="stop-color:#E82609"
+       id="stop3396-1" /><stop
+       offset="1"
+       style="stop-color:#E82609"
+       id="stop3398-2" /></linearGradient><linearGradient
+     id="XMLID_26_-2"
+     gradientUnits="userSpaceOnUse"
+     x1="99.074699"
+     y1="171.0332"
+     x2="52.817699"
+     y2="159.61659"><stop
+       offset="0"
+       style="stop-color:#8C0C01"
+       id="stop3403-0" /><stop
+       offset="0"
+       style="stop-color:#8C0C01"
+       id="stop3405-2" /><stop
+       offset="0.54"
+       style="stop-color:#990C00"
+       id="stop3407-1" /><stop
+       offset="0.99"
+       style="stop-color:#A80D0E"
+       id="stop3409-7" /><stop
+       offset="1"
+       style="stop-color:#A80D0E"
+       id="stop3411-5" /></linearGradient><linearGradient
+     id="XMLID_27_-1"
+     gradientUnits="userSpaceOnUse"
+     x1="178.52589"
+     y1="115.5146"
+     x2="137.43269"
+     y2="78.683998"><stop
+       offset="0"
+       style="stop-color:#7E110B"
+       id="stop3416-7" /><stop
+       offset="0"
+       style="stop-color:#7E110B"
+       id="stop3418-4" /><stop
+       offset="0.99"
+       style="stop-color:#9E0C00"
+       id="stop3420-1" /><stop
+       offset="1"
+       style="stop-color:#9E0C00"
+       id="stop3422-7" /></linearGradient><linearGradient
+     id="XMLID_28_-1"
+     gradientUnits="userSpaceOnUse"
+     x1="193.6235"
+     y1="47.937"
+     x2="173.15421"
+     y2="26.053801"><stop
+       offset="0"
+       style="stop-color:#79130D"
+       id="stop3427-1" /><stop
+       offset="0"
+       style="stop-color:#79130D"
+       id="stop3429-1" /><stop
+       offset="0.99"
+       style="stop-color:#9E120B"
+       id="stop3431-7" /><stop
+       offset="1"
+       style="stop-color:#9E120B"
+       id="stop3433-0" /></linearGradient><radialGradient
+     id="XMLID_29_-4"
+     cx="143.8315"
+     cy="79.388199"
+     r="50.357601"
+     gradientUnits="userSpaceOnUse"><stop
+       offset="0"
+       style="stop-color:#A80D00"
+       id="stop3440-0" /><stop
+       offset="0"
+       style="stop-color:#A80D00"
+       id="stop3442-8" /><stop
+       offset="0.99"
+       style="stop-color:#7E0E08"
+       id="stop3444-5" /><stop
+       offset="1"
+       style="stop-color:#7E0E08"
+       id="stop3446-1" /></radialGradient><radialGradient
+     id="XMLID_30_-6"
+     cx="74.0923"
+     cy="145.75101"
+     r="66.943703"
+     gradientUnits="userSpaceOnUse"><stop
+       offset="0"
+       style="stop-color:#A30C00"
+       id="stop3451-6" /><stop
+       offset="0"
+       style="stop-color:#A30C00"
+       id="stop3453-2" /><stop
+       offset="0.99"
+       style="stop-color:#800E08"
+       id="stop3455-1" /><stop
+       offset="1"
+       style="stop-color:#800E08"
+       id="stop3457-9" /></radialGradient><linearGradient
+     id="XMLID_31_-6"
+     gradientUnits="userSpaceOnUse"
+     x1="26.669901"
+     y1="197.33591"
+     x2="9.9886999"
+     y2="140.742"><stop
+       offset="0"
+       style="stop-color:#8B2114"
+       id="stop3462-4" /><stop
+       offset="0"
+       style="stop-color:#8B2114"
+       id="stop3464-8" /><stop
+       offset="0.43"
+       style="stop-color:#9E100A"
+       id="stop3466-0" /><stop
+       offset="0.99"
+       style="stop-color:#B3100C"
+       id="stop3468-8" /><stop
+       offset="1"
+       style="stop-color:#B3100C"
+       id="stop3470-1" /></linearGradient><linearGradient
+     id="XMLID_32_-0"
+     gradientUnits="userSpaceOnUse"
+     x1="154.6411"
+     y1="9.7979002"
+     x2="192.039"
+     y2="26.305901"><stop
+       offset="0"
+       style="stop-color:#B31000"
+       id="stop3475-2" /><stop
+       offset="0"
+       style="stop-color:#B31000"
+       id="stop3477-2" /><stop
+       offset="0.44"
+       style="stop-color:#910F08"
+       id="stop3479-9" /><stop
+       offset="0.99"
+       style="stop-color:#791C12"
+       id="stop3481-7" /><stop
+       offset="1"
+       style="stop-color:#791C12"
+       id="stop3483-5" /></linearGradient><linearGradient
+     y2="141.7533"
+     x2="132.27631"
+     y1="215.5488"
+     x1="174.0737"
+     gradientUnits="userSpaceOnUse"
+     id="linearGradient3448"
+     xlink:href="#XMLID_17_-9"
+     inkscape:collect="always" /></defs><sodipodi:namedview
+   pagecolor="#ffffff"
+   bordercolor="#666666"
+   borderopacity="1"
+   objecttolerance="10"
+   gridtolerance="10"
+   guidetolerance="10"
+   inkscape:pageopacity="0"
+   inkscape:pageshadow="2"
+   inkscape:window-width="1036"
+   inkscape:window-height="1124"
+   id="namedview3487"
+   showgrid="false"
+   inkscape:zoom="1.3412289"
+   inkscape:cx="99.065005"
+   inkscape:cy="98.790004"
+   inkscape:window-x="882"
+   inkscape:window-y="24"
+   inkscape:window-maximized="0"
+   inkscape:current-layer="Layer_1" />
+<linearGradient
+   id="XMLID_17_"
+   gradientUnits="userSpaceOnUse"
+   x1="174.0737"
+   y1="215.5488"
+   x2="132.2763"
+   y2="141.7533">
+	<stop
+   offset="0"
+   style="stop-color:#FB7655"
+   id="stop3272" />
+	<stop
+   offset="0"
+   style="stop-color:#FB7655"
+   id="stop3274" />
+	<stop
+   offset="0.41"
+   style="stop-color:#E42B1E"
+   id="stop3276" />
+	<stop
+   offset="0.99"
+   style="stop-color:#990000"
+   id="stop3278" />
+	<stop
+   offset="1"
+   style="stop-color:#990000"
+   id="stop3280" />
+</linearGradient>
+
+<linearGradient
+   id="XMLID_18_"
+   gradientUnits="userSpaceOnUse"
+   x1="194.895"
+   y1="153.5576"
+   x2="141.0276"
+   y2="117.4093">
+	<stop
+   offset="0"
+   style="stop-color:#871101"
+   id="stop3285" />
+	<stop
+   offset="0"
+   style="stop-color:#871101"
+   id="stop3287" />
+	<stop
+   offset="0.99"
+   style="stop-color:#911209"
+   id="stop3289" />
+	<stop
+   offset="1"
+   style="stop-color:#911209"
+   id="stop3291" />
+</linearGradient>
+
+<linearGradient
+   id="XMLID_19_"
+   gradientUnits="userSpaceOnUse"
+   x1="151.7954"
+   y1="217.7852"
+   x2="97.9297"
+   y2="181.638">
+	<stop
+   offset="0"
+   style="stop-color:#871101"
+   id="stop3296" />
+	<stop
+   offset="0"
+   style="stop-color:#871101"
+   id="stop3298" />
+	<stop
+   offset="0.99"
+   style="stop-color:#911209"
+   id="stop3300" />
+	<stop
+   offset="1"
+   style="stop-color:#911209"
+   id="stop3302" />
+</linearGradient>
+
+<linearGradient
+   id="XMLID_20_"
+   gradientUnits="userSpaceOnUse"
+   x1="38.6963"
+   y1="127.3906"
+   x2="47.0469"
+   y2="181.6614">
+	<stop
+   offset="0"
+   style="stop-color:#FFFFFF"
+   id="stop3307" />
+	<stop
+   offset="0"
+   style="stop-color:#FFFFFF"
+   id="stop3309" />
+	<stop
+   offset="0.23"
+   style="stop-color:#E57252"
+   id="stop3311" />
+	<stop
+   offset="0.46"
+   style="stop-color:#DE3B20"
+   id="stop3313" />
+	<stop
+   offset="0.99"
+   style="stop-color:#A60003"
+   id="stop3315" />
+	<stop
+   offset="1"
+   style="stop-color:#A60003"
+   id="stop3317" />
+</linearGradient>
+
+<linearGradient
+   id="XMLID_21_"
+   gradientUnits="userSpaceOnUse"
+   x1="96.1328"
+   y1="76.7153"
+   x2="99.2096"
+   y2="132.1021">
+	<stop
+   offset="0"
+   style="stop-color:#FFFFFF"
+   id="stop3322" />
+	<stop
+   offset="0"
+   style="stop-color:#FFFFFF"
+   id="stop3324" />
+	<stop
+   offset="0.23"
+   style="stop-color:#E4714E"
+   id="stop3326" />
+	<stop
+   offset="0.56"
+   style="stop-color:#BE1A0D"
+   id="stop3328" />
+	<stop
+   offset="0.99"
+   style="stop-color:#A80D00"
+   id="stop3330" />
+	<stop
+   offset="1"
+   style="stop-color:#A80D00"
+   id="stop3332" />
+</linearGradient>
+
+<linearGradient
+   id="XMLID_22_"
+   gradientUnits="userSpaceOnUse"
+   x1="147.103"
+   y1="25.521"
+   x2="156.3141"
+   y2="65.2162">
+	<stop
+   offset="0"
+   style="stop-color:#FFFFFF"
+   id="stop3337" />
+	<stop
+   offset="0"
+   style="stop-color:#FFFFFF"
+   id="stop3339" />
+	<stop
+   offset="0.18"
+   style="stop-color:#E46342"
+   id="stop3341" />
+	<stop
+   offset="0.4"
+   style="stop-color:#C82410"
+   id="stop3343" />
+	<stop
+   offset="0.99"
+   style="stop-color:#A80D00"
+   id="stop3345" />
+	<stop
+   offset="1"
+   style="stop-color:#A80D00"
+   id="stop3347" />
+</linearGradient>
+
+<linearGradient
+   id="XMLID_23_"
+   gradientUnits="userSpaceOnUse"
+   x1="118.9761"
+   y1="11.5415"
+   x2="158.6686"
+   y2="-8.3048">
+	<stop
+   offset="0"
+   style="stop-color:#FFFFFF"
+   id="stop3352" />
+	<stop
+   offset="0"
+   style="stop-color:#FFFFFF"
+   id="stop3354" />
+	<stop
+   offset="0.54"
+   style="stop-color:#C81F11"
+   id="stop3356" />
+	<stop
+   offset="0.99"
+   style="stop-color:#BF0905"
+   id="stop3358" />
+	<stop
+   offset="1"
+   style="stop-color:#BF0905"
+   id="stop3360" />
+</linearGradient>
+
+<linearGradient
+   id="XMLID_24_"
+   gradientUnits="userSpaceOnUse"
+   x1="3.9033"
+   y1="113.5547"
+   x2="7.1702"
+   y2="146.2628">
+	<stop
+   offset="0"
+   style="stop-color:#FFFFFF"
+   id="stop3365" />
+	<stop
+   offset="0"
+   style="stop-color:#FFFFFF"
+   id="stop3367" />
+	<stop
+   offset="0.31"
+   style="stop-color:#DE4024"
+   id="stop3369" />
+	<stop
+   offset="0.99"
+   style="stop-color:#BF190B"
+   id="stop3371" />
+	<stop
+   offset="1"
+   style="stop-color:#BF190B"
+   id="stop3373" />
+</linearGradient>
+
+
+<linearGradient
+   id="XMLID_25_"
+   gradientUnits="userSpaceOnUse"
+   x1="-18.5557"
+   y1="155.1045"
+   x2="135.0152"
+   y2="-2.8093">
+	<stop
+   offset="0"
+   style="stop-color:#BD0012"
+   id="stop3380" />
+	<stop
+   offset="0"
+   style="stop-color:#BD0012"
+   id="stop3382" />
+	<stop
+   offset="0.07"
+   style="stop-color:#FFFFFF"
+   id="stop3384" />
+	<stop
+   offset="0.17"
+   style="stop-color:#FFFFFF"
+   id="stop3386" />
+	<stop
+   offset="0.27"
+   style="stop-color:#C82F1C"
+   id="stop3388" />
+	<stop
+   offset="0.33"
+   style="stop-color:#820C01"
+   id="stop3390" />
+	<stop
+   offset="0.46"
+   style="stop-color:#A31601"
+   id="stop3392" />
+	<stop
+   offset="0.72"
+   style="stop-color:#B31301"
+   id="stop3394" />
+	<stop
+   offset="0.99"
+   style="stop-color:#E82609"
+   id="stop3396" />
+	<stop
+   offset="1"
+   style="stop-color:#E82609"
+   id="stop3398" />
+</linearGradient>
+
+<linearGradient
+   id="XMLID_26_"
+   gradientUnits="userSpaceOnUse"
+   x1="99.0747"
+   y1="171.0332"
+   x2="52.8177"
+   y2="159.6166">
+	<stop
+   offset="0"
+   style="stop-color:#8C0C01"
+   id="stop3403" />
+	<stop
+   offset="0"
+   style="stop-color:#8C0C01"
+   id="stop3405" />
+	<stop
+   offset="0.54"
+   style="stop-color:#990C00"
+   id="stop3407" />
+	<stop
+   offset="0.99"
+   style="stop-color:#A80D0E"
+   id="stop3409" />
+	<stop
+   offset="1"
+   style="stop-color:#A80D0E"
+   id="stop3411" />
+</linearGradient>
+
+<linearGradient
+   id="XMLID_27_"
+   gradientUnits="userSpaceOnUse"
+   x1="178.5259"
+   y1="115.5146"
+   x2="137.4327"
+   y2="78.684">
+	<stop
+   offset="0"
+   style="stop-color:#7E110B"
+   id="stop3416" />
+	<stop
+   offset="0"
+   style="stop-color:#7E110B"
+   id="stop3418" />
+	<stop
+   offset="0.99"
+   style="stop-color:#9E0C00"
+   id="stop3420" />
+	<stop
+   offset="1"
+   style="stop-color:#9E0C00"
+   id="stop3422" />
+</linearGradient>
+
+<linearGradient
+   id="XMLID_28_"
+   gradientUnits="userSpaceOnUse"
+   x1="193.6235"
+   y1="47.937"
+   x2="173.1542"
+   y2="26.0538">
+	<stop
+   offset="0"
+   style="stop-color:#79130D"
+   id="stop3427" />
+	<stop
+   offset="0"
+   style="stop-color:#79130D"
+   id="stop3429" />
+	<stop
+   offset="0.99"
+   style="stop-color:#9E120B"
+   id="stop3431" />
+	<stop
+   offset="1"
+   style="stop-color:#9E120B"
+   id="stop3433" />
+</linearGradient>
+
+
+<radialGradient
+   id="XMLID_29_"
+   cx="143.8315"
+   cy="79.3882"
+   r="50.3576"
+   gradientUnits="userSpaceOnUse">
+	<stop
+   offset="0"
+   style="stop-color:#A80D00"
+   id="stop3440" />
+	<stop
+   offset="0"
+   style="stop-color:#A80D00"
+   id="stop3442" />
+	<stop
+   offset="0.99"
+   style="stop-color:#7E0E08"
+   id="stop3444" />
+	<stop
+   offset="1"
+   style="stop-color:#7E0E08"
+   id="stop3446" />
+</radialGradient>
+
+<radialGradient
+   id="XMLID_30_"
+   cx="74.0923"
+   cy="145.751"
+   r="66.9437"
+   gradientUnits="userSpaceOnUse">
+	<stop
+   offset="0"
+   style="stop-color:#A30C00"
+   id="stop3451" />
+	<stop
+   offset="0"
+   style="stop-color:#A30C00"
+   id="stop3453" />
+	<stop
+   offset="0.99"
+   style="stop-color:#800E08"
+   id="stop3455" />
+	<stop
+   offset="1"
+   style="stop-color:#800E08"
+   id="stop3457" />
+</radialGradient>
+
+<linearGradient
+   id="XMLID_31_"
+   gradientUnits="userSpaceOnUse"
+   x1="26.6699"
+   y1="197.3359"
+   x2="9.9887"
+   y2="140.742">
+	<stop
+   offset="0"
+   style="stop-color:#8B2114"
+   id="stop3462" />
+	<stop
+   offset="0"
+   style="stop-color:#8B2114"
+   id="stop3464" />
+	<stop
+   offset="0.43"
+   style="stop-color:#9E100A"
+   id="stop3466" />
+	<stop
+   offset="0.99"
+   style="stop-color:#B3100C"
+   id="stop3468" />
+	<stop
+   offset="1"
+   style="stop-color:#B3100C"
+   id="stop3470" />
+</linearGradient>
+
+<linearGradient
+   id="XMLID_32_"
+   gradientUnits="userSpaceOnUse"
+   x1="154.6411"
+   y1="9.7979"
+   x2="192.039"
+   y2="26.3059">
+	<stop
+   offset="0"
+   style="stop-color:#B31000"
+   id="stop3475" />
+	<stop
+   offset="0"
+   style="stop-color:#B31000"
+   id="stop3477" />
+	<stop
+   offset="0.44"
+   style="stop-color:#910F08"
+   id="stop3479" />
+	<stop
+   offset="0.99"
+   style="stop-color:#791C12"
+   id="stop3481" />
+	<stop
+   offset="1"
+   style="stop-color:#791C12"
+   id="stop3483" />
+</linearGradient>
+
+<polygon
+   style="fill:url(#linearGradient3448);fill-rule:evenodd"
+   clip-rule="evenodd"
+   points="153.5,130.41 40.38,197.58 186.849,187.641 198.13,39.95 "
+   id="polygon3282" /><polygon
+   style="fill:url(#XMLID_18_-7);fill-rule:evenodd"
+   clip-rule="evenodd"
+   points="187.089,187.54 174.5,100.65 140.209,145.93 "
+   id="polygon3293" /><polygon
+   style="fill:url(#XMLID_19_-4);fill-rule:evenodd"
+   clip-rule="evenodd"
+   points="187.259,187.54 95.03,180.3 40.87,197.391 "
+   id="polygon3304" /><polygon
+   style="fill:url(#XMLID_20_-9);fill-rule:evenodd"
+   clip-rule="evenodd"
+   points="41,197.41 64.04,121.93 13.34,132.771 "
+   id="polygon3319" /><polygon
+   style="fill:url(#XMLID_21_-3);fill-rule:evenodd"
+   clip-rule="evenodd"
+   points="140.2,146.18 119,63.14 58.33,120.01 "
+   id="polygon3334" /><polygon
+   style="fill:url(#XMLID_22_-7);fill-rule:evenodd"
+   clip-rule="evenodd"
+   points="193.32,64.31 135.97,17.47 120,69.1 "
+   id="polygon3349" /><polygon
+   style="fill:url(#XMLID_23_-9);fill-rule:evenodd"
+   clip-rule="evenodd"
+   points="166.5,0.77 132.77,19.41 111.49,0.52 "
+   id="polygon3362" /><polygon
+   style="fill:url(#XMLID_24_-3);fill-rule:evenodd"
+   clip-rule="evenodd"
+   points="0,158.09 14.13,132.32 2.7,101.62 "
+   id="polygon3375" /><path
+   style="fill:#ffffff;fill-rule:evenodd"
+   inkscape:connector-curvature="0"
+   clip-rule="evenodd"
+   d="m 1.94,100.65 11.5,32.62 49.97,-11.211 57.05,-53.02 L 136.56,17.9 111.209,0 68.109,16.13 C 54.53,28.76 28.18,53.75 27.23,54.22 26.29,54.7 9.83,85.81 1.94,100.65 z"
+   id="path3377" /><path
+   style="fill:url(#XMLID_25_-9);fill-rule:evenodd"
+   inkscape:connector-curvature="0"
+   clip-rule="evenodd"
+   d="m 42.32,42.05 c 29.43,-29.18 67.37,-46.42 81.93,-31.73 14.551,14.69 -0.88,50.39 -30.31,79.56 -29.43,29.17 -66.9,47.36 -81.45,32.67 -14.56,-14.68 0.4,-51.33 29.83,-80.5 z"
+   id="path3400" /><path
+   style="fill:url(#XMLID_26_-2);fill-rule:evenodd"
+   inkscape:connector-curvature="0"
+   clip-rule="evenodd"
+   d="m 41,197.38 22.86,-75.72 75.92,24.39 C 112.33,171.79 81.8,193.55 41,197.38 z"
+   id="path3413" /><path
+   style="fill:url(#XMLID_27_-1);fill-rule:evenodd"
+   inkscape:connector-curvature="0"
+   clip-rule="evenodd"
+   d="m 120.56,68.89 19.49,77.2 C 162.98,121.98 183.56,96.06 193.639,64 l -73.079,4.89 z"
+   id="path3424" /><path
+   style="fill:url(#XMLID_28_-1);fill-rule:evenodd"
+   inkscape:connector-curvature="0"
+   clip-rule="evenodd"
+   d="m 193.44,64.39 c 7.8,-23.54 9.6,-57.31 -27.181,-63.58 l -30.18,16.67 57.361,46.91 z"
+   id="path3435" /><path
+   style="fill:#9e1209;fill-rule:evenodd"
+   inkscape:connector-curvature="0"
+   clip-rule="evenodd"
+   d="m 0,157.75 c 1.08,38.851 29.11,39.43 41.05,39.771 L 13.47,133.11 0,157.75 z"
+   id="path3437" /><path
+   style="fill:url(#XMLID_29_-4);fill-rule:evenodd"
+   inkscape:connector-curvature="0"
+   clip-rule="evenodd"
+   d="m 120.669,69.01 c 17.62,10.83 53.131,32.58 53.851,32.98 1.119,0.63 15.31,-23.93 18.53,-37.81 l -72.381,4.83 z"
+   id="path3448" /><path
+   style="fill:url(#XMLID_30_-6);fill-rule:evenodd"
+   inkscape:connector-curvature="0"
+   clip-rule="evenodd"
+   d="m 63.83,121.66 30.56,58.96 c 18.07,-9.8 32.22,-21.74 45.18,-34.53 L 63.83,121.66 z"
+   id="path3459" /><path
+   style="fill:url(#XMLID_31_-6);fill-rule:evenodd"
+   inkscape:connector-curvature="0"
+   clip-rule="evenodd"
+   d="m 13.35,133.19 -4.33,51.56 c 8.17,11.16 19.41,12.13 31.2,11.26 -8.53,-21.23 -25.57,-63.68 -26.87,-62.82 z"
+   id="path3472" /><path
+   style="fill:url(#XMLID_32_-0);fill-rule:evenodd"
+   inkscape:connector-curvature="0"
+   clip-rule="evenodd"
+   d="m 135.9,17.61 60.71,8.52 C 193.37,12.4 183.42,3.54 166.46,0.77 L 135.9,17.61 z"
+   id="path3485" /></svg>
\ No newline at end of file

From 3a3305540197f6eb1562c8d732fbbb121c917080 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Fri, 18 Feb 2022 11:50:06 +0700
Subject: [PATCH 091/163] =?UTF-8?q?=E2=9C=A8=20Add=20Security=20Policy?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 SECURITY.md | 15 +++++++++++++++
 1 file changed, 15 insertions(+)
 create mode 100644 SECURITY.md

diff --git a/SECURITY.md b/SECURITY.md
new file mode 100644
index 00000000..9e7d133b
--- /dev/null
+++ b/SECURITY.md
@@ -0,0 +1,15 @@
+# Security Policy
+
+## Supported Versions
+
+| Version      | Supported |
+|--------------|-----------|
+| 2.0.<latest> | ✅         |
+| 1.4.<latest> | ✅         |
+| older        | ⛔️        |
+
+## Reporting a Vulnerability
+
+Peter Boling is the primary maintainer of this gem. Please find a way
+to [contact him directly](https://railsbling.com/contact) to report the issue. Include as much relevant information as
+possible.

From f30a7bdcf02b512620968e11b9fb7cbf13ec68e7 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Fri, 18 Feb 2022 11:50:37 +0700
Subject: [PATCH 092/163] =?UTF-8?q?=E2=9C=A8=20The=20Best=20Badges?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 README.md | 161 +++++++++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 130 insertions(+), 31 deletions(-)

diff --git a/README.md b/README.md
index 1bad21ca..546bd46b 100644
--- a/README.md
+++ b/README.md
@@ -22,12 +22,14 @@ branch which for version 1.4.x releases. Version 2.0 is coming! ⚠️
 
 * [OAuth 2.0 Spec][oauth2-spec]
 * [OAuth 1.0 sibling gem][sibling-gem]
-* Help us reach the [2.0.0 release milestone][next-milestone] by submitting or reviewing PRs and issues.
+* Help us reach the [![2.0.0 release milestone][next-milestone-pct-img]][next-milestone-pct] by submitting or reviewing PRs and issues.
 * Oauth2 gem is _always_ looking for additional maintainers. See [#307][maintainers-discussion].
 
 [oauth2-spec]: https://oauth.net/2/
 [sibling-gem]: https://github.com/oauth-xx/oauth-ruby
-[next-milestone]: https://github.com/oauth-xx/oauth2/milestone/1
+[next-milestone-pct]: https://github.com/oauth-xx/oauth2/milestone/1
+[next-milestone-pct-img]: https://img.shields.io/github/milestones/progress-percent/oauth-xx/oauth2/1
+
 [maintainers-discussion]: https://github.com/oauth-xx/oauth2/issues/307
 
 ## Release Documentation
@@ -67,30 +69,130 @@ branch which for version 1.4.x releases. Version 2.0 is coming! ⚠️
 | < 1.0.0  | Find here    | https://github.com/oauth-xx/oauth2/tags                  |
 </details>
 
+<!--
+Numbering rows and badges in each row as a visual "database" lookup,
+    as the table is extremely dense, and it can be very difficult to find anything
+Putting one on each row here, to document the emoji that should be used, and for ease of copy/paste.
+
+row #s:
+1️⃣
+2️⃣
+3️⃣
+4️⃣
+5️⃣
+6️⃣
+7️⃣
+
+badge #s:
+⛳️
+🖇
+🏘
+🚎
+🖐
+🧮
+📗
+-->
+
+|     | Project               | oauth2                                                                                                                                                                                                                                                             |
+|:----|-----------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| 1️⃣ | name, license, docs   | [![RubyGems.org][⛳️name-img]][⛳️gem] [![License: MIT][🖇src-license-img]][🖇src-license] [![FOSSA][🏘fossa-img]][🏘fossa] [![RubyDoc.info][🚎yard-img]][🚎yard] [![InchCI][🖐inch-ci-img]][🚎yard]                                                                 |
+| 2️⃣ | version & activity    | [![Gem Version][⛳️version-img]][⛳️gem] [![Total Downloads][🖇DL-total-img]][⛳️gem] [![Download Rank][🏘DL-rank-img]][⛳️gem] [![Source Code][🚎src-home-img]][🚎src-home] [![Open PRs][🖐prs-open-img]][🖐prs-open] [![Closed PRs][🧮prs-closed-img]][🧮prs-closed] |
+| 3️⃣ | maintanence & linting | [![Maintainability][⛳cclim-maint-img]][⛳cclim-maint] [![Helpers][🖇triage-help-img]][🖇triage-help] [![Depfu][🏘depfu-img]][🏘depfu] [![Contributors][🚎contributors-img]][🚎contributors] [![Style][🖐style-wf-img]][🖐style-wf]                                  |
+| 4️⃣ | testing               | [![Build][⛳️tot-bld-img]][⛳️tot-bld] [![supported][🖇supported-wf-img]][🖇supported-wf] [![EOL & Code Coverage Build][🏘eol-wf-img]][🏘eol-wf] [![unsupported][🚎unsupported-wf-img]][🚎unsupported-wf]                                                            |
+| 5️⃣ | coverage & security   | [![CodeClimate][⛳cclim-cov-img]][⛳cclim-cov] [![CodeCov][🖇codecov-img]][🖇codecov] [![Coveralls][🏘coveralls-img]][🏘coveralls] [![Security Policy][🚎sec-pol-img])][🚎sec-pol] [![CodeQL][🖐codeQL-img]][🖐codeQL]                                               |
+| 7️⃣ | resources             | [![Discussion][⛳gh-discussions-img]][⛳gh-discussions] [![Get help on Codementor][🖇codementor-img]][🖇codementor] [![Chat][🏘chat-img]][🏘chat] [![Blog][🚎blog-img]][🚎blog] [![Blog][🖐wiki-img]][🖐wiki]                                                        |
+| 8️⃣ | spread 💖             | [![Liberapay Patrons][⛳liberapay-img]][⛳liberapay] [![Sponsor Me][🖇sponsor-img]][🖇sponsor] [![Tweet @ Peter][🏘tweet-img]][🏘tweet] [🌏][aboutme] [👼][angelme] [💻][coderme] [🌹][politicme]                                                                    |
+
+<!--
+The link tokens in the following sections should be kept ordered by the row and badge numbering scheme
+-->
+
+<!-- 1️⃣ name, license, docs -->
+[⛳️gem]: https://rubygems.org/gems/oauth2
+[⛳️name-img]: https://img.shields.io/badge/name-oauth2-brightgreen.svg?style=flat
+[🖇src-license]: https://opensource.org/licenses/MIT
+[🖇src-license-img]: https://img.shields.io/badge/License-MIT-green.svg
+[🏘fossa]: https://app.fossa.io/projects/git%2Bgithub.com%2Foauth-xx%2Foauth2?ref=badge_shield
+[🏘fossa-img]: https://app.fossa.io/api/projects/git%2Bgithub.com%2Foauth-xx%2Foauth2.svg?type=shield
+[🚎yard]: https://www.rubydoc.info/github/oauth-xx/oauth2
+[🚎yard-img]: https://img.shields.io/badge/documentation-rubydoc-brightgreen.svg?style=flat
+[🖐inch-ci-img]: http://inch-ci.org/github/oauth-xx/oauth2.png
+
+<!-- 2️⃣ version & activity -->
+[⛳️version-img]: http://img.shields.io/gem/v/oauth2.svg
+[🖇DL-total-img]: https://img.shields.io/gem/dt/oauth2.svg
+[🏘DL-rank-img]: https://img.shields.io/gem/rt/oauth2.svg
+[🚎src-home]: https://github.com/oauth-xx/oauth2
+[🚎src-home-img]: https://img.shields.io/badge/source-github-brightgreen.svg?style=flat
+[🖐prs-open]: https://github.com/oauth-xx/oauth2/pulls
+[🖐prs-open-img]: https://img.shields.io/github/issues-pr/oauth-xx/oauth2
+[🧮prs-closed]: https://github.com/oauth-xx/oauth2/pulls?q=is%3Apr+is%3Aclosed
+[🧮prs-closed-img]: https://img.shields.io/github/issues-pr-closed/oauth-xx/oauth2
+
+<!-- 3️⃣ maintanence & linting -->
+[⛳cclim-maint]: https://codeclimate.com/github/oauth-xx/oauth2/maintainability
+[⛳cclim-maint-img]: https://api.codeclimate.com/v1/badges/688c612528ff90a46955/maintainability
+[🖇triage-help]: https://www.codetriage.com/oauth-xx/oauth2
+[🖇triage-help-img]: https://www.codetriage.com/oauth-xx/oauth2/badges/users.svg
+[🏘depfu]: https://depfu.com/github/oauth-xx/oauth2?project_id=4445
+[🏘depfu-img]: https://badges.depfu.com/badges/6d34dc1ba682bbdf9ae2a97848241743/count.svg
+[🚎contributors]: https://github.com/oauth-xx/oauth2/graphs/contributors
+[🚎contributors-img]: https://img.shields.io/github/contributors-anon/oauth-xx/oauth2
+[🖐style-wf]: https://github.com/oauth-xx/oauth2/actions/workflows/style.yml
+[🖐style-wf-img]: https://github.com/oauth-xx/oauth2/actions/workflows/style.yml/badge.svg
+
+<!-- 4️⃣ testing -->
+[⛳️tot-bld]: https://actions-badge.atrox.dev/oauth-xx/oauth2/goto
+[⛳️tot-bld-img]: https://img.shields.io/endpoint.svg?url=https%3A%2F%2Factions-badge.atrox.dev%2Foauth-xx%2Foauth2%2Fbadge&style=flat
+[🖇supported-wf]: https://github.com/oauth-xx/oauth2/actions/workflows/supported.yml
+[🖇supported-wf-img]: https://github.com/oauth-xx/oauth2/actions/workflows/supported.yml/badge.svg
+[🏘eol-wf]: https://github.com/oauth-xx/oauth2/actions/workflows/coverage.yml
+[🏘eol-wf-img]: https://github.com/oauth-xx/oauth2/actions/workflows/coverage.yml/badge.svg
+[🚎unsupported-wf]: https://github.com/oauth-xx/oauth2/actions/workflows/unsupported.yml
+[🚎unsupported-wf-img]: https://github.com/oauth-xx/oauth2/actions/workflows/unsupported.yml/badge.svg
+[🖐issues]: https://github.com/oauth-xx/oauth2/issues
+[🖐issues-img]: https://github.com/oauth-xx/oauth2/issues
+
+<!-- 5️⃣ coverage & security -->
+[⛳cclim-cov]: https://codeclimate.com/github/oauth-xx/oauth2/test_coverage
+[⛳cclim-cov-img]: https://api.codeclimate.com/v1/badges/688c612528ff90a46955/test_coverage
+[🖇codecov-img]: https://codecov.io/gh/oauth-xx/oauth2/branch/1-4-stable/graph/badge.svg?token=bNqSzNiuo2
+[🖇codecov]: https://codecov.io/gh/oauth-xx/oauth2
+[🏘coveralls]: https://coveralls.io/github/oauth-xx/oauth2?branch=1-4-stable
+[🏘coveralls-img]: https://coveralls.io/repos/github/oauth-xx/oauth2/badge.svg?branch=1-4-stable
+[🚎sec-pol]: SECURITY.md
+[🚎sec-pol-img]: https://img.shields.io/badge/security-policy-brightgreen.svg?style=flat
+[🖐codeQL]: https://github.com/oauth-xx/oauth2/security/code-scanning
+[🖐codeQL-img]: https://github.com/oauth-xx/oauth2/actions/workflows/codeql-analysis.yml/badge.svg
+
+<!-- 7️⃣ resources -->
+[⛳gh-discussions]: https://github.com/oauth-xx/oauth2/discussions
+[⛳gh-discussions-img]: https://img.shields.io/github/discussions/oauth-xx/oauth2
+[🖇codementor]: https://www.codementor.io/peterboling?utm_source=github&utm_medium=button&utm_term=peterboling&utm_campaign=github
+[🖇codementor-img]: https://cdn.codementor.io/badges/get_help_github.svg
+[🏘chat]: https://gitter.im/oauth-xx/oauth2
+[🏘chat-img]: https://img.shields.io/gitter/room/oauth-xx/oauth2.svg
+[🚎blog]: http://www.railsbling.com/tags/oauth2/
+[🚎blog-img]: https://img.shields.io/badge/blog-railsbling-brightgreen.svg?style=flat
+[🖐wiki]: https://github.com/oauth-xx/oauth2/wiki
+[🖐wiki-img]: https://img.shields.io/badge/wiki-examples-brightgreen.svg?style=flat
+
+<!-- 8️⃣ spread 💖 -->
+[⛳liberapay-img]: https://img.shields.io/liberapay/patrons/pboling.svg?logo=liberapay
+[⛳liberapay]: https://liberapay.com/pboling/donate
+[🖇sponsor-img]: https://img.shields.io/badge/sponsor-pboling.svg?style=social&logo=github
+[🖇sponsor]: https://github.com/sponsors/pboling
+[🏘tweet-img]: https://img.shields.io/twitter/follow/galtzo.svg?style=social&label=Follow
+[🏘tweet]: http://twitter.com/galtzo
+
+<!-- Maintainer Contact Links -->
+[railsbling]: http://www.railsbling.com
+[peterboling]: http://www.peterboling.com
+[aboutme]: https://about.me/peter.boling
+[angelme]: https://angel.co/peter-boling
+[coderme]:http://coderwall.com/pboling
+[politicme]: https://nationalprogressiveparty.org
 
-[![Gem Version](http://img.shields.io/gem/v/oauth2.svg)][gem]
-[![Total Downloads](https://img.shields.io/gem/dt/oauth2.svg)][gem]
-[![Downloads Today](https://img.shields.io/gem/rt/oauth2.svg)][gem]
-[![Build Status](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Factions-badge.atrox.dev%2Foauth-xx%2Foauth2%2Fbadge&style=flat)][github-actions]
-[![Test Coverage](https://api.codeclimate.com/v1/badges/688c612528ff90a46955/test_coverage)][codeclimate-coverage]
-[![Maintainability](https://api.codeclimate.com/v1/badges/688c612528ff90a46955/maintainability)][codeclimate-maintainability]
-[![Depfu](https://badges.depfu.com/badges/6d34dc1ba682bbdf9ae2a97848241743/count.svg)][depfu]
-[![Open Source Helpers](https://www.codetriage.com/oauth-xx/oauth2/badges/users.svg)][code-triage]
-[![Chat](https://img.shields.io/gitter/room/oauth-xx/oauth2.svg)](https://gitter.im/oauth-xx/oauth2)
-[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)][source-license]
-[![Documentation](http://inch-ci.org/github/oauth-xx/oauth2.png)][inch-ci]
-[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Foauth-xx%2Foauth2.svg?type=shield)][fossa1]
-
-[gem]: https://rubygems.org/gems/oauth2
-[github-actions]: https://actions-badge.atrox.dev/oauth-xx/oauth2/goto
-[coveralls]: https://coveralls.io/r/oauth-xx/oauth2
-[codeclimate-maintainability]: https://codeclimate.com/github/oauth-xx/oauth2/maintainability
-[codeclimate-coverage]: https://codeclimate.com/github/oauth-xx/oauth2/test_coverage
-[depfu]: https://depfu.com/github/oauth-xx/oauth2
-[source-license]: https://opensource.org/licenses/MIT
-[inch-ci]: http://inch-ci.org/github/oauth-xx/oauth2
-[code-triage]: https://www.codetriage.com/oauth-xx/oauth2
-[fossa1]: https://app.fossa.io/projects/git%2Bgithub.com%2Foauth-xx%2Foauth2?ref=badge_shield
 
 ## Installation
 
@@ -133,6 +235,7 @@ If you would like to add support for additional engines,
 | older                | N/A                | Best of luck to you!    | Please upgrade!        |                        |
 
 NOTE: Once 2.0 is released, the 1.4 series will only receive critical bug and security updates.
+See [SECURITY.md][🚎sec-pol]
 
 <details>
   <summary>Ruby Compatibility Policy</summary>
@@ -153,14 +256,10 @@ of a major release, support for that Ruby version may be dropped.
 
 ## Resources
 
-* [View Source on GitHub][code]
+* [View Source on GitHub][🚎src-home]
 * [Report Issues on GitHub][issues]
 * [Read More at the Wiki][wiki]
 
-[code]: https://github.com/oauth-xx/oauth2
-[issues]: https://github.com/oauth-xx/oauth2/issues
-[wiki]: https://github.com/oauth-xx/oauth2/wiki
-
 ## Usage Examples
 
 ```ruby
@@ -286,7 +385,7 @@ spec.add_dependency 'oauth2', '~> 1.4'
 
 ## License
 
-[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)][source-license]
+[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)][src-license]
 
 - Copyright (c) 2011-2013 Michael Bleigh and Intridea, Inc.
 - Copyright (c) 2017-2018 [oauth-xx organization][oauth-xx]

From 450c70c8b4b772cadabc5138b0c1f0c5b7e474b2 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Fri, 18 Feb 2022 12:08:06 +0700
Subject: [PATCH 093/163] =?UTF-8?q?=E2=9C=8F=EF=B8=8F=20Fix=20typos?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 README.md | 9 +--------
 1 file changed, 1 insertion(+), 8 deletions(-)

diff --git a/README.md b/README.md
index 546bd46b..c38b246a 100644
--- a/README.md
+++ b/README.md
@@ -29,7 +29,6 @@ branch which for version 1.4.x releases. Version 2.0 is coming! ⚠️
 [sibling-gem]: https://github.com/oauth-xx/oauth-ruby
 [next-milestone-pct]: https://github.com/oauth-xx/oauth2/milestone/1
 [next-milestone-pct-img]: https://img.shields.io/github/milestones/progress-percent/oauth-xx/oauth2/1
-
 [maintainers-discussion]: https://github.com/oauth-xx/oauth2/issues/307
 
 ## Release Documentation
@@ -254,12 +253,6 @@ fashion. If critical issues for a particular implementation exist at the time
 of a major release, support for that Ruby version may be dropped.
 </details>
 
-## Resources
-
-* [View Source on GitHub][🚎src-home]
-* [Report Issues on GitHub][issues]
-* [Read More at the Wiki][wiki]
-
 ## Usage Examples
 
 ```ruby
@@ -385,7 +378,7 @@ spec.add_dependency 'oauth2', '~> 1.4'
 
 ## License
 
-[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)][src-license]
+[![License: MIT][🖇src-license-img]][🖇src-license]
 
 - Copyright (c) 2011-2013 Michael Bleigh and Intridea, Inc.
 - Copyright (c) 2017-2018 [oauth-xx organization][oauth-xx]

From b2d422da4245e1409f571cbbf29f76334868ea45 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Fri, 18 Feb 2022 12:10:04 +0700
Subject: [PATCH 094/163] =?UTF-8?q?=F0=9F=93=84=20Update=20Copyright?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 LICENSE   | 2 +-
 README.md | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/LICENSE b/LICENSE
index 96eb4e8f..0d3a82cd 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,7 +1,7 @@
 MIT License
 
 Copyright (c) 2011 - 2013 Michael Bleigh and Intridea, Inc.
-Copyright (c) 2017 - 2021 oauth-xx organization, https://github.com/oauth-xx
+Copyright (c) 2017 - 2022 oauth-xx organization, https://github.com/oauth-xx
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
diff --git a/README.md b/README.md
index c38b246a..73ff745b 100644
--- a/README.md
+++ b/README.md
@@ -381,7 +381,7 @@ spec.add_dependency 'oauth2', '~> 1.4'
 [![License: MIT][🖇src-license-img]][🖇src-license]
 
 - Copyright (c) 2011-2013 Michael Bleigh and Intridea, Inc.
-- Copyright (c) 2017-2018 [oauth-xx organization][oauth-xx]
+- Copyright (c) 2017-2022 [oauth-xx organization][oauth-xx]
 - See [LICENSE][license] for details.
 
 [![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Foauth-xx%2Foauth2.svg?type=large)][fossa2]

From 88cc416bc0a6b31e6bce3bdb6e9930ec13991dae Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Fri, 18 Feb 2022 12:11:22 +0700
Subject: [PATCH 095/163] =?UTF-8?q?=F0=9F=9A=9A=20Fix=20resource=20paths?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 README.md | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/README.md b/README.md
index 73ff745b..c345ee77 100644
--- a/README.md
+++ b/README.md
@@ -159,7 +159,7 @@ The link tokens in the following sections should be kept ordered by the row and
 [🖇codecov]: https://codecov.io/gh/oauth-xx/oauth2
 [🏘coveralls]: https://coveralls.io/github/oauth-xx/oauth2?branch=1-4-stable
 [🏘coveralls-img]: https://coveralls.io/repos/github/oauth-xx/oauth2/badge.svg?branch=1-4-stable
-[🚎sec-pol]: SECURITY.md
+[🚎sec-pol]: https://github.com/oauth-xx/oauth2/blob/master/SECURITY.md
 [🚎sec-pol-img]: https://img.shields.io/badge/security-policy-brightgreen.svg?style=flat
 [🖐codeQL]: https://github.com/oauth-xx/oauth2/security/code-scanning
 [🖐codeQL-img]: https://github.com/oauth-xx/oauth2/actions/workflows/codeql-analysis.yml/badge.svg
@@ -386,7 +386,7 @@ spec.add_dependency 'oauth2', '~> 1.4'
 
 [![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Foauth-xx%2Foauth2.svg?type=large)][fossa2]
 
-[license]: LICENSE
+[license]: https://github.com/oauth-xx/oauth2/blob/master/LICENSE
 [oauth-xx]: https://github.com/oauth-xx
 [fossa2]: https://app.fossa.io/projects/git%2Bgithub.com%2Foauth-xx%2Foauth2?ref=badge_large
 

From e6d9688faec39e5a9ae840ea8f784633d504e3e6 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Fri, 18 Feb 2022 12:16:55 +0700
Subject: [PATCH 096/163] =?UTF-8?q?=F0=9F=9A=9A=20Fix=20numbering?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 README.md | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/README.md b/README.md
index c345ee77..431e293a 100644
--- a/README.md
+++ b/README.md
@@ -99,8 +99,8 @@ badge #s:
 | 3️⃣ | maintanence & linting | [![Maintainability][⛳cclim-maint-img]][⛳cclim-maint] [![Helpers][🖇triage-help-img]][🖇triage-help] [![Depfu][🏘depfu-img]][🏘depfu] [![Contributors][🚎contributors-img]][🚎contributors] [![Style][🖐style-wf-img]][🖐style-wf]                                  |
 | 4️⃣ | testing               | [![Build][⛳️tot-bld-img]][⛳️tot-bld] [![supported][🖇supported-wf-img]][🖇supported-wf] [![EOL & Code Coverage Build][🏘eol-wf-img]][🏘eol-wf] [![unsupported][🚎unsupported-wf-img]][🚎unsupported-wf]                                                            |
 | 5️⃣ | coverage & security   | [![CodeClimate][⛳cclim-cov-img]][⛳cclim-cov] [![CodeCov][🖇codecov-img]][🖇codecov] [![Coveralls][🏘coveralls-img]][🏘coveralls] [![Security Policy][🚎sec-pol-img])][🚎sec-pol] [![CodeQL][🖐codeQL-img]][🖐codeQL]                                               |
-| 7️⃣ | resources             | [![Discussion][⛳gh-discussions-img]][⛳gh-discussions] [![Get help on Codementor][🖇codementor-img]][🖇codementor] [![Chat][🏘chat-img]][🏘chat] [![Blog][🚎blog-img]][🚎blog] [![Blog][🖐wiki-img]][🖐wiki]                                                        |
-| 8️⃣ | spread 💖             | [![Liberapay Patrons][⛳liberapay-img]][⛳liberapay] [![Sponsor Me][🖇sponsor-img]][🖇sponsor] [![Tweet @ Peter][🏘tweet-img]][🏘tweet] [🌏][aboutme] [👼][angelme] [💻][coderme] [🌹][politicme]                                                                    |
+| 6️⃣ | resources             | [![Discussion][⛳gh-discussions-img]][⛳gh-discussions] [![Get help on Codementor][🖇codementor-img]][🖇codementor] [![Chat][🏘chat-img]][🏘chat] [![Blog][🚎blog-img]][🚎blog] [![Blog][🖐wiki-img]][🖐wiki]                                                        |
+| 7️⃣ | spread 💖             | [![Liberapay Patrons][⛳liberapay-img]][⛳liberapay] [![Sponsor Me][🖇sponsor-img]][🖇sponsor] [![Tweet @ Peter][🏘tweet-img]][🏘tweet] [🌏][aboutme] [👼][angelme] [💻][coderme] [🌹][politicme]                                                                    |
 
 <!--
 The link tokens in the following sections should be kept ordered by the row and badge numbering scheme
@@ -164,7 +164,7 @@ The link tokens in the following sections should be kept ordered by the row and
 [🖐codeQL]: https://github.com/oauth-xx/oauth2/security/code-scanning
 [🖐codeQL-img]: https://github.com/oauth-xx/oauth2/actions/workflows/codeql-analysis.yml/badge.svg
 
-<!-- 7️⃣ resources -->
+<!-- 6️⃣ resources -->
 [⛳gh-discussions]: https://github.com/oauth-xx/oauth2/discussions
 [⛳gh-discussions-img]: https://img.shields.io/github/discussions/oauth-xx/oauth2
 [🖇codementor]: https://www.codementor.io/peterboling?utm_source=github&utm_medium=button&utm_term=peterboling&utm_campaign=github
@@ -176,7 +176,7 @@ The link tokens in the following sections should be kept ordered by the row and
 [🖐wiki]: https://github.com/oauth-xx/oauth2/wiki
 [🖐wiki-img]: https://img.shields.io/badge/wiki-examples-brightgreen.svg?style=flat
 
-<!-- 8️⃣ spread 💖 -->
+<!-- 7️⃣ spread 💖 -->
 [⛳liberapay-img]: https://img.shields.io/liberapay/patrons/pboling.svg?logo=liberapay
 [⛳liberapay]: https://liberapay.com/pboling/donate
 [🖇sponsor-img]: https://img.shields.io/badge/sponsor-pboling.svg?style=social&logo=github

From c35c5af1ce675c5c61494f7852fd5e30243b2a2d Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Fri, 18 Feb 2022 12:25:02 +0700
Subject: [PATCH 097/163] =?UTF-8?q?=E2=9C=A8=20Ruby=20Version=20and=20Engi?=
 =?UTF-8?q?ne=20Policies?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 README.md | 22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/README.md b/README.md
index 431e293a..1b9e540f 100644
--- a/README.md
+++ b/README.md
@@ -217,7 +217,7 @@ Targeted ruby compatibility is non-EOL versions of Ruby, currently 2.7, 3.0 and
 Ruby is limited to 1.9+ in the gemspec for the 1.4.x series and will be 2.2+ for 2.x releases (see `master` branch).
 
 <details>
-  <summary>Ruby Engine Compatibility</summary>
+  <summary>Ruby Engine Compatibility Policy</summary>
 
 This gem is tested against MRI, JRuby, and Truffleruby.
 Each of those has varying versions that target a specific version of MRI Ruby.
@@ -227,17 +227,8 @@ If you would like to add support for additional engines,
   then submit a PR to the correct maintenance branch as according to the table below.
 </details>
 
-| Ruby OAuth 2 Version | Maintenance Branch | Supported Officially    | Supported Unofficially | Supported Incidentally |
-|----------------------|--------------------|-------------------------|-------------------------------------------------|
-| 2.0.x (unreleased)   | `master`           | 2.7, 3.0, 3.1           | 2.6, 2.5               | 2.4, 2.3, 2.2          |
-| 1.4.x                | `1-4-stable`       | 2.5, 2.6, 2.7, 3.0, 3.1 | 2.1, 2.2, 2.3, 2.4     | 2.0, 1.9               |
-| older                | N/A                | Best of luck to you!    | Please upgrade!        |                        |
-
-NOTE: Once 2.0 is released, the 1.4 series will only receive critical bug and security updates.
-See [SECURITY.md][🚎sec-pol]
-
 <details>
-  <summary>Ruby Compatibility Policy</summary>
+  <summary>Ruby Version Compatibility Policy</summary>
 
 If something doesn't work on one of these interpreters, it's a bug.
 
@@ -253,6 +244,15 @@ fashion. If critical issues for a particular implementation exist at the time
 of a major release, support for that Ruby version may be dropped.
 </details>
 
+|     | Ruby OAuth 2 Version | Maintenance Branch | Supported Officially    | Supported Unofficially | Supported Incidentally |
+|:----|----------------------|--------------------|-------------------------|------------------------|------------------------|
+| 1️⃣ | 2.0.x (unreleased)   | `master`           | 2.7, 3.0, 3.1           | 2.6, 2.5               | 2.4, 2.3, 2.2          |
+| 2️⃣ | 1.4.x                | `1-4-stable`       | 2.5, 2.6, 2.7, 3.0, 3.1 | 2.1, 2.2, 2.3, 2.4     | 2.0, 1.9               |
+| 3️⃣ | older                | N/A                | Best of luck to you!    | Please upgrade!        |                        |
+
+NOTE: Once 2.0 is released, the 1.4 series will only receive critical bug and security updates.
+See [SECURITY.md][🚎sec-pol]
+
 ## Usage Examples
 
 ```ruby

From d5a8fe8505f6f1961c445d8b35e5895e82ca06a1 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Fri, 18 Feb 2022 12:38:51 +0700
Subject: [PATCH 098/163] =?UTF-8?q?=E2=9C=A8=20Add=20Kloc=20Roll?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 README.md | 20 +++++++++++---------
 1 file changed, 11 insertions(+), 9 deletions(-)

diff --git a/README.md b/README.md
index 1b9e540f..1556c70d 100644
--- a/README.md
+++ b/README.md
@@ -92,15 +92,15 @@ badge #s:
 📗
 -->
 
-|     | Project               | oauth2                                                                                                                                                                                                                                                             |
-|:----|-----------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| 1️⃣ | name, license, docs   | [![RubyGems.org][⛳️name-img]][⛳️gem] [![License: MIT][🖇src-license-img]][🖇src-license] [![FOSSA][🏘fossa-img]][🏘fossa] [![RubyDoc.info][🚎yard-img]][🚎yard] [![InchCI][🖐inch-ci-img]][🚎yard]                                                                 |
-| 2️⃣ | version & activity    | [![Gem Version][⛳️version-img]][⛳️gem] [![Total Downloads][🖇DL-total-img]][⛳️gem] [![Download Rank][🏘DL-rank-img]][⛳️gem] [![Source Code][🚎src-home-img]][🚎src-home] [![Open PRs][🖐prs-open-img]][🖐prs-open] [![Closed PRs][🧮prs-closed-img]][🧮prs-closed] |
-| 3️⃣ | maintanence & linting | [![Maintainability][⛳cclim-maint-img]][⛳cclim-maint] [![Helpers][🖇triage-help-img]][🖇triage-help] [![Depfu][🏘depfu-img]][🏘depfu] [![Contributors][🚎contributors-img]][🚎contributors] [![Style][🖐style-wf-img]][🖐style-wf]                                  |
-| 4️⃣ | testing               | [![Build][⛳️tot-bld-img]][⛳️tot-bld] [![supported][🖇supported-wf-img]][🖇supported-wf] [![EOL & Code Coverage Build][🏘eol-wf-img]][🏘eol-wf] [![unsupported][🚎unsupported-wf-img]][🚎unsupported-wf]                                                            |
-| 5️⃣ | coverage & security   | [![CodeClimate][⛳cclim-cov-img]][⛳cclim-cov] [![CodeCov][🖇codecov-img]][🖇codecov] [![Coveralls][🏘coveralls-img]][🏘coveralls] [![Security Policy][🚎sec-pol-img])][🚎sec-pol] [![CodeQL][🖐codeQL-img]][🖐codeQL]                                               |
-| 6️⃣ | resources             | [![Discussion][⛳gh-discussions-img]][⛳gh-discussions] [![Get help on Codementor][🖇codementor-img]][🖇codementor] [![Chat][🏘chat-img]][🏘chat] [![Blog][🚎blog-img]][🚎blog] [![Blog][🖐wiki-img]][🖐wiki]                                                        |
-| 7️⃣ | spread 💖             | [![Liberapay Patrons][⛳liberapay-img]][⛳liberapay] [![Sponsor Me][🖇sponsor-img]][🖇sponsor] [![Tweet @ Peter][🏘tweet-img]][🏘tweet] [🌏][aboutme] [👼][angelme] [💻][coderme] [🌹][politicme]                                                                    |
+|     | Project               | oauth2                                                                                                                                                                                                                                                               |
+|:----|-----------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| 1️⃣ | name, license, docs   | [![RubyGems.org][⛳️name-img]][⛳️gem] [![License: MIT][🖇src-license-img]][🖇src-license] [![FOSSA][🏘fossa-img]][🏘fossa] [![RubyDoc.info][🚎yard-img]][🚎yard] [![InchCI][🖐inch-ci-img]][🚎yard]                                                                   |
+| 2️⃣ | version & activity    | [![Gem Version][⛳️version-img]][⛳️gem] [![Total Downloads][🖇DL-total-img]][⛳️gem] [![Download Rank][🏘DL-rank-img]][⛳️gem] [![Source Code][🚎src-home-img]][🚎src-home] [![Open PRs][🖐prs-open-img]][🖐prs-open] [![Closed PRs][🧮prs-closed-img]][🧮prs-closed]   |
+| 3️⃣ | maintanence & linting | [![Maintainability][⛳cclim-maint-img]][⛳cclim-maint] [![Helpers][🖇triage-help-img]][🖇triage-help] [![Depfu][🏘depfu-img]][🏘depfu] [![Contributors][🚎contributors-img]][🚎contributors] [![Style][🖐style-wf-img]][🖐style-wf] [![Kloc Roll][🧮kloc-img]][🧮kloc] |
+| 4️⃣ | testing               | [![Build][⛳️tot-bld-img]][⛳️tot-bld] [![supported][🖇supported-wf-img]][🖇supported-wf] [![EOL & Code Coverage Build][🏘eol-wf-img]][🏘eol-wf] [![unsupported][🚎unsupported-wf-img]][🚎unsupported-wf]                                                              |
+| 5️⃣ | coverage & security   | [![CodeClimate][⛳cclim-cov-img]][⛳cclim-cov] [![CodeCov][🖇codecov-img]][🖇codecov] [![Coveralls][🏘coveralls-img]][🏘coveralls] [![Security Policy][🚎sec-pol-img])][🚎sec-pol] [![CodeQL][🖐codeQL-img]][🖐codeQL]                                                 |
+| 6️⃣ | resources             | [![Discussion][⛳gh-discussions-img]][⛳gh-discussions] [![Get help on Codementor][🖇codementor-img]][🖇codementor] [![Chat][🏘chat-img]][🏘chat] [![Blog][🚎blog-img]][🚎blog] [![Blog][🖐wiki-img]][🖐wiki]                                                          |
+| 7️⃣ | spread 💖             | [![Liberapay Patrons][⛳liberapay-img]][⛳liberapay] [![Sponsor Me][🖇sponsor-img]][🖇sponsor] [![Tweet @ Peter][🏘tweet-img]][🏘tweet] [🌏][aboutme] [👼][angelme] [💻][coderme] [🌹][politicme]                                                                      |
 
 <!--
 The link tokens in the following sections should be kept ordered by the row and badge numbering scheme
@@ -139,6 +139,8 @@ The link tokens in the following sections should be kept ordered by the row and
 [🚎contributors-img]: https://img.shields.io/github/contributors-anon/oauth-xx/oauth2
 [🖐style-wf]: https://github.com/oauth-xx/oauth2/actions/workflows/style.yml
 [🖐style-wf-img]: https://github.com/oauth-xx/oauth2/actions/workflows/style.yml/badge.svg
+[🧮kloc]: https://www.youtube.com/watch?v=dQw4w9WgXcQ
+[🧮kloc-img]: https://img.shields.io/tokei/lines/github.com/oauth-xx/oauth2
 
 <!-- 4️⃣ testing -->
 [⛳️tot-bld]: https://actions-badge.atrox.dev/oauth-xx/oauth2/goto

From acbc4d71f200d5141ed06e75750b08d131d0b74a Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Fri, 18 Feb 2022 12:40:55 +0700
Subject: [PATCH 099/163] =?UTF-8?q?=F0=9F=9A=A8=20Lint=20Fixes?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 README.md | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/README.md b/README.md
index 1556c70d..90ef0e35 100644
--- a/README.md
+++ b/README.md
@@ -15,7 +15,7 @@ OAuth 2.0 focuses on client developer simplicity while providing specific author
 This is a RubyGem for implementing OAuth 2.0 clients and servers in Ruby applications.
 See the sibling `oauth` gem for OAuth 1.0 implementations in Ruby.
 
-⚠️ **_WARNING_**: You are viewing the `README` of the soon-to-be-deprecated `1-4-stable` 
+⚠️ **_WARNING_**: You are viewing the `README` of the soon-to-be-deprecated `1-4-stable`
 branch which for version 1.4.x releases. Version 2.0 is coming! ⚠️
 
 ---
@@ -224,7 +224,7 @@ Ruby is limited to 1.9+ in the gemspec for the 1.4.x series and will be 2.2+ for
 This gem is tested against MRI, JRuby, and Truffleruby.
 Each of those has varying versions that target a specific version of MRI Ruby.
 This gem should work in the just-listed Ruby engines according to the targeted MRI compatibility in the table below.
-If you would like to add support for additional engines, 
+If you would like to add support for additional engines,
   first make sure Github Actions supports the engine,
   then submit a PR to the correct maintenance branch as according to the table below.
 </details>
@@ -288,8 +288,8 @@ require 'oauth2'
 client = OAuth2::Client.new(
   'client_id',
   'client_secret',
-  site: 'https://example.org',
-  logger: Logger.new('example.log', 'weekly')
+  :site => 'https://example.org',
+  :logger => Logger.new('example.log', 'weekly')
 )
 ```
 </details>

From e1d9250ad7f5c3a01d8ca95087ab0e06404d08af Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Fri, 18 Feb 2022 12:52:08 +0700
Subject: [PATCH 100/163] =?UTF-8?q?=F0=9F=9A=A8=20Lint=20Fixes?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 .rubocop.yml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/.rubocop.yml b/.rubocop.yml
index 58996661..81f22bf8 100644
--- a/.rubocop.yml
+++ b/.rubocop.yml
@@ -12,6 +12,7 @@ require:
 AllCops:
   NewCops: enable
   DisplayCopNames: true # Display the name of the failing cops
+  TargetRubyVersion: 2.5
   Exclude:
     - 'gemfiles/vendor/**/*'
     - 'vendor/**/*'

From 9e9ed16293db6987cff60ed9ab5a99d83d2f0e85 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Fri, 18 Feb 2022 13:16:49 +0700
Subject: [PATCH 101/163] =?UTF-8?q?=E2=9C=8F=EF=B8=8F=20Fix=20typo?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 README.md | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/README.md b/README.md
index 90ef0e35..0dc8ecf7 100644
--- a/README.md
+++ b/README.md
@@ -92,15 +92,15 @@ badge #s:
 📗
 -->
 
-|     | Project               | oauth2                                                                                                                                                                                                                                                               |
-|:----|-----------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| 1️⃣ | name, license, docs   | [![RubyGems.org][⛳️name-img]][⛳️gem] [![License: MIT][🖇src-license-img]][🖇src-license] [![FOSSA][🏘fossa-img]][🏘fossa] [![RubyDoc.info][🚎yard-img]][🚎yard] [![InchCI][🖐inch-ci-img]][🚎yard]                                                                   |
-| 2️⃣ | version & activity    | [![Gem Version][⛳️version-img]][⛳️gem] [![Total Downloads][🖇DL-total-img]][⛳️gem] [![Download Rank][🏘DL-rank-img]][⛳️gem] [![Source Code][🚎src-home-img]][🚎src-home] [![Open PRs][🖐prs-open-img]][🖐prs-open] [![Closed PRs][🧮prs-closed-img]][🧮prs-closed]   |
+|     | Project               | oauth2                                                                                                                                                                                                                                                              |
+|:----|-----------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| 1️⃣ | name, license, docs   | [![RubyGems.org][⛳️name-img]][⛳️gem] [![License: MIT][🖇src-license-img]][🖇src-license] [![FOSSA][🏘fossa-img]][🏘fossa] [![RubyDoc.info][🚎yard-img]][🚎yard] [![InchCI][🖐inch-ci-img]][🚎yard]                                                                  |
+| 2️⃣ | version & activity    | [![Gem Version][⛳️version-img]][⛳️gem] [![Total Downloads][🖇DL-total-img]][⛳️gem] [![Download Rank][🏘DL-rank-img]][⛳️gem] [![Source Code][🚎src-home-img]][🚎src-home] [![Open PRs][🖐prs-open-img]][🖐prs-open] [![Closed PRs][🧮prs-closed-img]][🧮prs-closed]  |
 | 3️⃣ | maintanence & linting | [![Maintainability][⛳cclim-maint-img]][⛳cclim-maint] [![Helpers][🖇triage-help-img]][🖇triage-help] [![Depfu][🏘depfu-img]][🏘depfu] [![Contributors][🚎contributors-img]][🚎contributors] [![Style][🖐style-wf-img]][🖐style-wf] [![Kloc Roll][🧮kloc-img]][🧮kloc] |
-| 4️⃣ | testing               | [![Build][⛳️tot-bld-img]][⛳️tot-bld] [![supported][🖇supported-wf-img]][🖇supported-wf] [![EOL & Code Coverage Build][🏘eol-wf-img]][🏘eol-wf] [![unsupported][🚎unsupported-wf-img]][🚎unsupported-wf]                                                              |
-| 5️⃣ | coverage & security   | [![CodeClimate][⛳cclim-cov-img]][⛳cclim-cov] [![CodeCov][🖇codecov-img]][🖇codecov] [![Coveralls][🏘coveralls-img]][🏘coveralls] [![Security Policy][🚎sec-pol-img])][🚎sec-pol] [![CodeQL][🖐codeQL-img]][🖐codeQL]                                                 |
-| 6️⃣ | resources             | [![Discussion][⛳gh-discussions-img]][⛳gh-discussions] [![Get help on Codementor][🖇codementor-img]][🖇codementor] [![Chat][🏘chat-img]][🏘chat] [![Blog][🚎blog-img]][🚎blog] [![Blog][🖐wiki-img]][🖐wiki]                                                          |
-| 7️⃣ | spread 💖             | [![Liberapay Patrons][⛳liberapay-img]][⛳liberapay] [![Sponsor Me][🖇sponsor-img]][🖇sponsor] [![Tweet @ Peter][🏘tweet-img]][🏘tweet] [🌏][aboutme] [👼][angelme] [💻][coderme] [🌹][politicme]                                                                      |
+| 4️⃣ | testing               | [![Build][⛳️tot-bld-img]][⛳️tot-bld] [![supported][🖇supported-wf-img]][🖇supported-wf] [![EOL & Code Coverage Build][🏘eol-wf-img]][🏘eol-wf] [![unsupported][🚎unsupported-wf-img]][🚎unsupported-wf]                                                             |
+| 5️⃣ | coverage & security   | [![CodeClimate][⛳cclim-cov-img]][⛳cclim-cov] [![CodeCov][🖇codecov-img]][🖇codecov] [![Coveralls][🏘coveralls-img]][🏘coveralls] [![Security Policy][🚎sec-pol-img]][🚎sec-pol] [![CodeQL][🖐codeQL-img]][🖐codeQL]                                                 |
+| 6️⃣ | resources             | [![Discussion][⛳gh-discussions-img]][⛳gh-discussions] [![Get help on Codementor][🖇codementor-img]][🖇codementor] [![Chat][🏘chat-img]][🏘chat] [![Blog][🚎blog-img]][🚎blog] [![Blog][🖐wiki-img]][🖐wiki]                                                         |
+| 7️⃣ | spread 💖             | [![Liberapay Patrons][⛳liberapay-img]][⛳liberapay] [![Sponsor Me][🖇sponsor-img]][🖇sponsor] [![Tweet @ Peter][🏘tweet-img]][🏘tweet] [🌏][aboutme] [👼][angelme] [💻][coderme] [🌹][politicme]                                                                     |
 
 <!--
 The link tokens in the following sections should be kept ordered by the row and badge numbering scheme

From 13ca2b36ee43fd64a884f885fd09d9c6806d3456 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Fri, 18 Feb 2022 13:32:22 +0700
Subject: [PATCH 102/163] =?UTF-8?q?=F0=9F=91=B7=20Turn=20on=20Branch=20Cov?=
 =?UTF-8?q?erage?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 .simplecov     | 27 +++++++++++++++++++++++++++
 spec/helper.rb | 30 +-----------------------------
 2 files changed, 28 insertions(+), 29 deletions(-)
 create mode 100644 .simplecov

diff --git a/.simplecov b/.simplecov
new file mode 100644
index 00000000..829a7c6f
--- /dev/null
+++ b/.simplecov
@@ -0,0 +1,27 @@
+SimpleCov.start do
+  enable_coverage :branch
+  primary_coverage :branch
+
+  if ENV['CI'] || ENV['CODECOV']
+    require 'simplecov-lcov'
+    require 'simplecov-cobertura'
+    require 'coveralls'
+
+    SimpleCov::Formatter::LcovFormatter.config do |c|
+      c.report_with_single_file = true
+      c.single_report_path = 'coverage/lcov.info'
+    end
+
+    SimpleCov.formatters = [
+      SimpleCov::Formatter::CoberturaFormatter,
+      SimpleCov::Formatter::HTMLFormatter,
+      SimpleCov::Formatter::LcovFormatter,
+      Coveralls::SimpleCov::Formatter,
+    ]
+  else
+    formatter SimpleCov::Formatter::HTMLFormatter
+  end
+
+  add_filter '/spec'
+  minimum_coverage(86)
+end
diff --git a/spec/helper.rb b/spec/helper.rb
index fdbab2eb..d62d71ee 100644
--- a/spec/helper.rb
+++ b/spec/helper.rb
@@ -5,35 +5,7 @@
 coverage = minimum_version.call('2.7')
 debug = minimum_version.call('2.5')
 
-if coverage
-  require 'simplecov'
-
-  SimpleCov.start do
-    if ENV['CI'] || ENV['CODECOV']
-      require 'simplecov-lcov'
-      require 'simplecov-cobertura'
-      require 'coveralls'
-
-      SimpleCov::Formatter::LcovFormatter.config do |c|
-        c.report_with_single_file = true
-        c.single_report_path = 'coverage/lcov.info'
-      end
-
-      SimpleCov.formatters = [
-        SimpleCov::Formatter::HTMLFormatter,
-        SimpleCov::Formatter::LcovFormatter,
-        SimpleCov::Formatter::CoberturaFormatter,
-        Coveralls::SimpleCov::Formatter,
-      ]
-    else
-      formatter SimpleCov::Formatter::HTMLFormatter
-    end
-
-    add_filter '/spec'
-    minimum_coverage(95)
-  end
-end
-
+require 'simplecov' if coverage
 require 'byebug' if DEBUG && debug
 
 require 'oauth2'

From d8dd9d37adcfd4c601d3670c49632ad2dae2df35 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Fri, 18 Feb 2022 13:50:57 +0700
Subject: [PATCH 103/163] =?UTF-8?q?=F0=9F=94=96=20Prepare=20for=20release?=
 =?UTF-8?q?=201.4.8?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 CHANGELOG.md          | 10 ++++++++++
 README.md             | 23 ++++++++++++-----------
 lib/oauth2/version.rb |  2 +-
 3 files changed, 23 insertions(+), 12 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4cdc524a..45f03b47 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,6 +3,16 @@ All notable changes to this project will be documented in this file.
 
 ## unreleased
 
+## [1.4.8] - 2022-02-18
+
+- MFA is now required to push new gem versions (@pboling)
+- README overhaul w/ new Ruby Verion and Engine compatibility policies (@pboling)
+- [#569](https://github.com/oauth-xx/oauth2/pull/569) Backport fixes ([#561](https://github.com/oauth-xx/oauth2/pull/561) by @ryogift), and add more fixes, to allow faraday 1.x and 2.x (@jrochkind)
+- Improve Code Coverage tracking (Coveralls, CodeCov, CodeClimate), and enable branch coverage (@pboling)
+- Add CodeQL, Security Policy, Funding info (@pboling)
+- Added Ruby 3.1, jruby, jruby-head, truffleruby, truffleruby-head to build matrix (@pboling)
+- [#543](https://github.com/oauth-xx/oauth2/pull/543) - Support for more modern Open SSL libraries (@pboling)
+
 ## [1.4.7] - 2021-03-19
 
 - [#541](https://github.com/oauth-xx/oauth2/pull/541) - Backport fix to expires_at handling [#533](https://github.com/oauth-xx/oauth2/pull/533) to 1-4-stable branch. (@dobon)
diff --git a/README.md b/README.md
index 0dc8ecf7..ee0764ba 100644
--- a/README.md
+++ b/README.md
@@ -22,7 +22,7 @@ branch which for version 1.4.x releases. Version 2.0 is coming! ⚠️
 
 * [OAuth 2.0 Spec][oauth2-spec]
 * [OAuth 1.0 sibling gem][sibling-gem]
-* Help us reach the [![2.0.0 release milestone][next-milestone-pct-img]][next-milestone-pct] by submitting or reviewing PRs and issues.
+* Help us finish release [![2.0.0 release milestone][next-milestone-pct-img]][next-milestone-pct] by submitting or reviewing PRs and issues.
 * Oauth2 gem is _always_ looking for additional maintainers. See [#307][maintainers-discussion].
 
 [oauth2-spec]: https://oauth.net/2/
@@ -36,16 +36,17 @@ branch which for version 1.4.x releases. Version 2.0 is coming! ⚠️
 <details>
   <summary>1.4.x Readmes</summary>
 
-| Version  | Release Date | Readme                                                   |
-|----------|--------------|----------------------------------------------------------|
-| 1.4.7    | Mar 18, 2021 | https://github.com/oauth-xx/oauth2/blob/v1.4.7/README.md |
-| 1.4.6    | Mar 18, 2021 | https://github.com/oauth-xx/oauth2/blob/v1.4.6/README.md |
-| 1.4.5    | Mar 18, 2021 | https://github.com/oauth-xx/oauth2/blob/v1.4.5/README.md |
-| 1.4.4    | Feb 12, 2020 | https://github.com/oauth-xx/oauth2/blob/v1.4.4/README.md |
-| 1.4.3    | Jan 29, 2020 | https://github.com/oauth-xx/oauth2/blob/v1.4.3/README.md |
-| 1.4.2    | Oct 1, 2019  | https://github.com/oauth-xx/oauth2/blob/v1.4.2/README.md |
-| 1.4.1    | Oct 13, 2018 | https://github.com/oauth-xx/oauth2/blob/v1.4.1/README.md |
-| 1.4.0    | Jun 9, 2017  | https://github.com/oauth-xx/oauth2/blob/v1.4.0/README.md |
+| Version | Release Date | Readme                                                   |
+|---------|--------------|----------------------------------------------------------|
+| 1.4.8   | Feb 18, 2022 | https://github.com/oauth-xx/oauth2/blob/v1.4.8/README.md |
+| 1.4.7   | Mar 18, 2021 | https://github.com/oauth-xx/oauth2/blob/v1.4.7/README.md |
+| 1.4.6   | Mar 18, 2021 | https://github.com/oauth-xx/oauth2/blob/v1.4.6/README.md |
+| 1.4.5   | Mar 18, 2021 | https://github.com/oauth-xx/oauth2/blob/v1.4.5/README.md |
+| 1.4.4   | Feb 12, 2020 | https://github.com/oauth-xx/oauth2/blob/v1.4.4/README.md |
+| 1.4.3   | Jan 29, 2020 | https://github.com/oauth-xx/oauth2/blob/v1.4.3/README.md |
+| 1.4.2   | Oct 1, 2019  | https://github.com/oauth-xx/oauth2/blob/v1.4.2/README.md |
+| 1.4.1   | Oct 13, 2018 | https://github.com/oauth-xx/oauth2/blob/v1.4.1/README.md |
+| 1.4.0   | Jun 9, 2017  | https://github.com/oauth-xx/oauth2/blob/v1.4.0/README.md |
 </details>
 
 <details>
diff --git a/lib/oauth2/version.rb b/lib/oauth2/version.rb
index 9dba3aa2..4d91969b 100644
--- a/lib/oauth2/version.rb
+++ b/lib/oauth2/version.rb
@@ -24,7 +24,7 @@ def minor
     #
     # @return [Integer]
     def patch
-      7
+      8
     end
 
     # The pre-release version, if any

From 934faa899c7731df627093f4d76139ab40380709 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Fri, 18 Feb 2022 14:01:45 +0700
Subject: [PATCH 104/163] =?UTF-8?q?=F0=9F=94=96=20Add=20link=20to=20tag=20?=
 =?UTF-8?q?diff=20for=201.4.8=20release?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 CHANGELOG.md | 1 +
 1 file changed, 1 insertion(+)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 45f03b47..689df016 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -183,4 +183,5 @@ All notable changes to this project will be documented in this file.
 [1.4.5]: https://github.com/oauth-xx/oauth2/compare/v1.4.4...v1.4.5
 [1.4.6]: https://github.com/oauth-xx/oauth2/compare/v1.4.5...v1.4.6
 [1.4.7]: https://github.com/oauth-xx/oauth2/compare/v1.4.6...v1.4.7
+[1.4.8]: https://github.com/oauth-xx/oauth2/compare/v1.4.7...v1.4.8
 [unreleased]: https://github.com/oauth-xx/oauth2/compare/v1.4.1...HEAD

From a0b0a06812a4e7062be3ea4c42034cdcf9df5038 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Fri, 18 Feb 2022 14:13:27 +0700
Subject: [PATCH 105/163] =?UTF-8?q?=E2=9C=8F=EF=B8=8F=20Fix=20typos=20in?=
 =?UTF-8?q?=20release=20dates?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 README.md | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/README.md b/README.md
index ee0764ba..f5e83496 100644
--- a/README.md
+++ b/README.md
@@ -39,8 +39,8 @@ branch which for version 1.4.x releases. Version 2.0 is coming! ⚠️
 | Version | Release Date | Readme                                                   |
 |---------|--------------|----------------------------------------------------------|
 | 1.4.8   | Feb 18, 2022 | https://github.com/oauth-xx/oauth2/blob/v1.4.8/README.md |
-| 1.4.7   | Mar 18, 2021 | https://github.com/oauth-xx/oauth2/blob/v1.4.7/README.md |
-| 1.4.6   | Mar 18, 2021 | https://github.com/oauth-xx/oauth2/blob/v1.4.6/README.md |
+| 1.4.7   | Mar 19, 2021 | https://github.com/oauth-xx/oauth2/blob/v1.4.7/README.md |
+| 1.4.6   | Mar 19, 2021 | https://github.com/oauth-xx/oauth2/blob/v1.4.6/README.md |
 | 1.4.5   | Mar 18, 2021 | https://github.com/oauth-xx/oauth2/blob/v1.4.5/README.md |
 | 1.4.4   | Feb 12, 2020 | https://github.com/oauth-xx/oauth2/blob/v1.4.4/README.md |
 | 1.4.3   | Jan 29, 2020 | https://github.com/oauth-xx/oauth2/blob/v1.4.3/README.md |

From a87f7744a187cd8fae7289c383e7ce1429407540 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Sat, 19 Feb 2022 00:52:08 +0700
Subject: [PATCH 106/163] =?UTF-8?q?=F0=9F=9A=A8=20Update=20rubocop=20confi?=
 =?UTF-8?q?g?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 .rubocop_todo.yml | 46 +++++++++++++++-------------------------------
 1 file changed, 15 insertions(+), 31 deletions(-)

diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml
index f430c2d1..9168f954 100644
--- a/.rubocop_todo.yml
+++ b/.rubocop_todo.yml
@@ -1,6 +1,6 @@
 # This configuration was generated by
 # `rubocop --auto-gen-config`
-# on 2021-03-18 18:59:52 UTC using RuboCop version 1.11.0.
+# on 2022-02-18 17:51:21 UTC using RuboCop version 1.25.1.
 # The point is for the user to remove these configuration records
 # one by one as the offenses are removed from the code base.
 # Note that changes in the inspected code, or installation of new
@@ -20,28 +20,33 @@ Lint/UselessAssignment:
     - '**/*.markdown'
     - 'spec/oauth2/client_spec.rb'
 
+# Offense count: 1
+# Configuration parameters: IgnoredMethods, CountRepeatedAttributes.
+Metrics/AbcSize:
+  Max: 43
+
 # Offense count: 1
 # Configuration parameters: CountComments, CountAsOne, ExcludedMethods, IgnoredMethods.
 # IgnoredMethods: refine
 Metrics/BlockLength:
   Max: 27
 
-# Offense count: 4
+# Offense count: 2
 # Configuration parameters: IgnoredMethods.
 Metrics/CyclomaticComplexity:
   Max: 11
 
-# Offense count: 1
+# Offense count: 7
 # Configuration parameters: CountComments, CountAsOne, ExcludedMethods, IgnoredMethods.
 Metrics/MethodLength:
-  Max: 18
+  Max: 37
 
-# Offense count: 3
+# Offense count: 1
 # Configuration parameters: IgnoredMethods.
 Metrics/PerceivedComplexity:
   Max: 11
 
-# Offense count: 14
+# Offense count: 3
 # Configuration parameters: EnforcedStyle, CheckMethodNames, CheckSymbols, AllowedIdentifiers.
 # SupportedStyles: snake_case, normalcase, non_integer
 # AllowedIdentifiers: capture3, iso8601, rfc1123_date, rfc822, rfc2822, rfc3339
@@ -49,11 +54,6 @@ Naming/VariableNumber:
   Exclude:
     - 'Gemfile'
 
-# Offense count: 1
-Packaging/GemspecGit:
-  Exclude:
-    - 'oauth2.gemspec'
-
 # Offense count: 2
 # Configuration parameters: MinSize.
 Performance/CollectionLiteralInLoop:
@@ -75,38 +75,22 @@ RSpec/LeakyConstantDeclaration:
   Exclude:
     - 'spec/oauth2/client_spec.rb'
 
-# Offense count: 8
-# Configuration parameters: AllowSubject.
-RSpec/MultipleMemoizedHelpers:
-  Max: 6
-
 # Offense count: 1
+# Cop supports --auto-correct.
 Rake/Desc:
   Exclude:
     - 'Rakefile'
 
-# Offense count: 40
+# Offense count: 37
 # Cop supports --auto-correct.
 # Configuration parameters: EnforcedStyle.
 # SupportedStyles: always, always_true, never
 Style/FrozenStringLiteralComment:
   Enabled: false
 
-# Offense count: 1
-Style/MixinUsage:
-  Exclude:
-    - 'spec/helper.rb'
-
-# Offense count: 1
-# Cop supports --auto-correct.
-# Configuration parameters: ConvertCodeThatCanStartToReturnNil, AllowedMethods.
-# AllowedMethods: present?, blank?, presence, try, try!
-Style/SafeNavigation:
-  Exclude:
-    - 'lib/oauth2/error.rb'
-
 # Offense count: 3
-# Cop supports --auto-correct.
+# Cop supports --auto-correct-all.
+# Configuration parameters: Mode.
 Style/StringConcatenation:
   Exclude:
     - 'lib/oauth2/authenticator.rb'

From 179aab1cb81c478c17f90a2e7da20959a46897e1 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Sat, 19 Feb 2022 00:52:50 +0700
Subject: [PATCH 107/163] =?UTF-8?q?=F0=9F=9A=91=EF=B8=8F=20Fixes=20#572?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

- Backported fix from master:  https://github.com/oauth-xx/oauth2/pull/331
- 1-4-stable updated with several other parity changes from master

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 lib/oauth2/access_token.rb       |   4 +-
 lib/oauth2/client.rb             | 118 ++++++++++++++++++++-----------
 spec/oauth2/access_token_spec.rb |   2 +-
 3 files changed, 80 insertions(+), 44 deletions(-)

diff --git a/lib/oauth2/access_token.rb b/lib/oauth2/access_token.rb
index 228b99e6..90bff28d 100644
--- a/lib/oauth2/access_token.rb
+++ b/lib/oauth2/access_token.rb
@@ -38,7 +38,7 @@ def from_kvform(client, kvform)
     # @option opts [String] :header_format ('Bearer %s') the string format to use for the Authorization header
     # @option opts [String] :param_name ('access_token') the parameter name to use for transmission of the
     #    Access Token value in :body or :query transmission mode
-    def initialize(client, token, opts = {}) # rubocop:disable Metrics/AbcSize
+    def initialize(client, token, opts = {})
       @client = client
       @token = token.to_s
       opts = opts.dup
@@ -151,7 +151,7 @@ def headers
 
   private
 
-    def configure_authentication!(opts) # rubocop:disable Metrics/AbcSize
+    def configure_authentication!(opts)
       case options[:mode]
       when :header
         opts[:headers] ||= {}
diff --git a/lib/oauth2/client.rb b/lib/oauth2/client.rb
index 3a11aa27..500d5932 100644
--- a/lib/oauth2/client.rb
+++ b/lib/oauth2/client.rb
@@ -2,6 +2,7 @@
 require 'logger'
 
 module OAuth2
+  ConnectionError = Class.new(Faraday::ConnectionFailed)
   # The OAuth2::Client class
   class Client # rubocop:disable Metrics/ClassLength
     RESERVED_PARAM_KEYS = %w[headers parse].freeze
@@ -16,17 +17,18 @@ class Client # rubocop:disable Metrics/ClassLength
     #
     # @param [String] client_id the client_id value
     # @param [String] client_secret the client_secret value
-    # @param [Hash] opts the options to create the client with
-    # @option opts [String] :site the OAuth2 provider site host
-    # @option opts [String] :redirect_uri the absolute URI to the Redirection Endpoint for use in authorization grants and token exchange
-    # @option opts [String] :authorize_url ('/oauth/authorize') absolute or relative URL path to the Authorization endpoint
-    # @option opts [String] :token_url ('/oauth/token') absolute or relative URL path to the Token endpoint
-    # @option opts [Symbol] :token_method (:post) HTTP method to use to request token (:get or :post)
-    # @option opts [Symbol] :auth_scheme (:basic_auth) HTTP method to use to authorize request (:basic_auth or :request_body)
-    # @option opts [Hash] :connection_opts ({}) Hash of connection options to pass to initialize Faraday with
-    # @option opts [FixNum] :max_redirects (5) maximum number of redirects to follow
-    # @option opts [Boolean] :raise_errors (true) whether or not to raise an OAuth2::Error on responses with 400+ status codes
-    # @option opts [Proc] :extract_access_token  proc that extracts the access token from the response
+    # @param [Hash] options the options to create the client with
+    # @option options [String] :site the OAuth2 provider site host
+    # @option options [String] :redirect_uri the absolute URI to the Redirection Endpoint for use in authorization grants and token exchange
+    # @option options [String] :authorize_url ('/oauth/authorize') absolute or relative URL path to the Authorization endpoint
+    # @option options [String] :token_url ('/oauth/token') absolute or relative URL path to the Token endpoint
+    # @option options [Symbol] :token_method (:post) HTTP method to use to request token (:get or :post)
+    # @option options [Symbol] :auth_scheme (:basic_auth) HTTP method to use to authorize request (:basic_auth or :request_body)
+    # @option options [Hash] :connection_opts ({}) Hash of connection options to pass to initialize Faraday with
+    # @option options [FixNum] :max_redirects (5) maximum number of redirects to follow
+    # @option options [Boolean] :raise_errors (true) whether or not to raise an OAuth2::Error on responses with 400+ status codes
+    # @option options [Logger] :logger (::Logger.new($stdout)) which logger to use when OAUTH_DEBUG is enabled
+    # @option options [Proc] (DEPRECATED) :extract_access_token  proc that extracts the access token from the response
     # @yield [builder] The Faraday connection builder
     def initialize(client_id, client_secret, options = {}, &block)
       opts = options.dup
@@ -34,24 +36,22 @@ def initialize(client_id, client_secret, options = {}, &block)
       @secret = client_secret
       @site = opts.delete(:site)
       ssl = opts.delete(:ssl)
-
-      @options = {
-        :authorize_url => '/oauth/authorize',
-        :token_url => '/oauth/token',
-        :token_method => :post,
-        :auth_scheme => :request_body,
-        :connection_opts => {},
-        :connection_build => block,
-        :max_redirects => 5,
-        :raise_errors => true,
-        :extract_access_token => DEFAULT_EXTRACT_ACCESS_TOKEN,
-      }.merge(opts)
+      @options = {:authorize_url => '/oauth/authorize',
+                  :token_url => '/oauth/token',
+                  :token_method => :post,
+                  :auth_scheme => :request_body,
+                  :connection_opts => {},
+                  :connection_build => block,
+                  :max_redirects => 5,
+                  :raise_errors => true,
+                  :extract_access_token => DEFAULT_EXTRACT_ACCESS_TOKEN, # DEPRECATED
+                  :logger => ::Logger.new($stdout)}.merge(opts)
       @options[:connection_opts][:ssl] = ssl if ssl
     end
 
     # Set the site host
     #
-    # @param [String] the OAuth2 provider site host
+    # @param value [String] the OAuth2 provider site host
     def site=(value)
       @connection = nil
       @site = value
@@ -61,8 +61,12 @@ def site=(value)
     def connection
       @connection ||=
         Faraday.new(site, options[:connection_opts]) do |builder|
+          oauth_debug_logging(builder)
           if options[:connection_build]
             options[:connection_build].call(builder)
+          else
+            builder.request :url_encoded             # form-encode POST params
+            builder.adapter Faraday.default_adapter  # make requests with Net::HTTP
           end
         end
     end
@@ -94,15 +98,18 @@ def token_url(params = nil)
     #   code response for this request.  Will default to client option
     # @option opts [Symbol] :parse @see Response::initialize
     # @yield [req] The Faraday request
-    def request(verb, url, opts = {}) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
-      connection.response :logger, ::Logger.new($stdout) if ENV['OAUTH_DEBUG'] == 'true'
-
+    def request(verb, url, opts = {}) # rubocop:disable Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity, Metrics/AbcSize
       url = connection.build_url(url).to_s
 
-      response = connection.run_request(verb, url, opts[:body], opts[:headers]) do |req|
-        req.params.update(opts[:params]) if opts[:params]
-        yield(req) if block_given?
+      begin
+        response = connection.run_request(verb, url, opts[:body], opts[:headers]) do |req|
+          req.params.update(opts[:params]) if opts[:params]
+          yield(req) if block_given?
+        end
+      rescue Faraday::ConnectionFailed => e
+        raise ConnectionError, e
       end
+
       response = Response.new(response, :parse => opts[:parse])
 
       case response.status
@@ -115,7 +122,13 @@ def request(verb, url, opts = {}) # rubocop:disable Metrics/MethodLength, Metric
           verb = :get
           opts.delete(:body)
         end
-        request(verb, response.headers['location'], opts)
+        location = response.headers['location']
+        if location
+          request(verb, location, opts)
+        else
+          error = Error.new(response)
+          raise(error, "Got #{response.status} status code, but no Location header was present")
+        end
       when 200..299, 300..399
         # on non-redirecting 3xx statuses, just return the response
         response
@@ -133,11 +146,11 @@ def request(verb, url, opts = {}) # rubocop:disable Metrics/MethodLength, Metric
 
     # Initializes an AccessToken by making a request to the token endpoint
     #
-    # @param [Hash] params a Hash of params for the token endpoint
-    # @param [Hash] access token options, to pass to the AccessToken object
-    # @param [Class] class of access token for easier subclassing OAuth2::AccessToken
+    # @param params [Hash] a Hash of params for the token endpoint
+    # @param access_token_opts [Hash] access token options, to pass to the AccessToken object
+    # @param access_token_class [Class] class of access token for easier subclassing OAuth2::AccessToken
     # @return [AccessToken] the initialized AccessToken
-    def get_token(params, access_token_opts = {}, extract_access_token = options[:extract_access_token]) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
+    def get_token(params, access_token_opts = {}, extract_access_token = options[:extract_access_token]) # # rubocop:disable Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity Metrics/AbcSize, Metrics/MethodLength
       params = params.map do |key, value|
         if RESERVED_PARAM_KEYS.include?(key)
           [key.to_sym, value]
@@ -147,7 +160,7 @@ def get_token(params, access_token_opts = {}, extract_access_token = options[:ex
       end
       params = Hash[params]
 
-      params = Authenticator.new(id, secret, options[:auth_scheme]).apply(params)
+      params = authenticator.apply(params)
       opts = {:raise_errors => options[:raise_errors], :parse => params.delete(:parse)}
       headers = params.delete(:headers) || {}
       if options[:token_method] == :post
@@ -157,8 +170,9 @@ def get_token(params, access_token_opts = {}, extract_access_token = options[:ex
         opts[:params] = params
         opts[:headers] = {}
       end
-      opts[:headers].merge!(headers)
-      response = request(options[:token_method], token_url, opts)
+      opts[:headers] = opts[:headers].merge(headers)
+      http_method = options[:token_method]
+      response = request(http_method, token_url, opts)
 
       access_token = begin
         build_access_token(response, access_token_opts, extract_access_token)
@@ -166,10 +180,18 @@ def get_token(params, access_token_opts = {}, extract_access_token = options[:ex
         nil
       end
 
-      if options[:raise_errors] && !access_token
+      response_contains_token = access_token || (
+                                  response.parsed.is_a?(Hash) &&
+                                  (response.parsed['access_token'] || response.parsed['id_token'])
+                                )
+
+      if options[:raise_errors] && !response_contains_token
         error = Error.new(response)
         raise(error)
+      elsif !response_contains_token
+        return nil
       end
+
       access_token
     end
 
@@ -236,19 +258,33 @@ def redirection_params
 
   private
 
+    # Returns the authenticator object
+    #
+    # @return [Authenticator] the initialized Authenticator
+    def authenticator
+      Authenticator.new(id, secret, options[:auth_scheme])
+    end
+
+    # Builds the access token from the response of the HTTP call
+    #
+    # @return [AccessToken] the initialized AccessToken
     def build_access_token(response, access_token_opts, extract_access_token)
       parsed_response = response.parsed.dup
       return unless parsed_response.is_a?(Hash)
 
       hash = parsed_response.merge(access_token_opts)
 
-      # Provide backwards compatibility for old AcessToken.form_hash pattern
-      # Should be deprecated in 2.x
+      # Provide backwards compatibility for old AccessToken.form_hash pattern
+      # Will be deprecated in 2.x
       if extract_access_token.is_a?(Class) && extract_access_token.respond_to?(:from_hash)
         extract_access_token.from_hash(self, hash)
       else
         extract_access_token.call(self, hash)
       end
     end
+
+    def oauth_debug_logging(builder)
+      builder.response :logger, options[:logger], :bodies => true if ENV['OAUTH_DEBUG'] == 'true'
+    end
   end
 end
diff --git a/spec/oauth2/access_token_spec.rb b/spec/oauth2/access_token_spec.rb
index 3aa34395..8bf4c5ea 100644
--- a/spec/oauth2/access_token_spec.rb
+++ b/spec/oauth2/access_token_spec.rb
@@ -30,7 +30,7 @@
       expect(target.params['foo']).to eq('bar')
     end
 
-    def assert_initialized_token(target) # rubocop:disable Metrics/AbcSize
+    def assert_initialized_token(target)
       expect(target.token).to eq(token)
       expect(target).to be_expires
       expect(target.params.keys).to include('foo')

From ed288af7443bbc7621d148798840183c3d5e6839 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Sat, 19 Feb 2022 02:26:12 +0700
Subject: [PATCH 108/163] =?UTF-8?q?=F0=9F=8E=A8=20Improving=20client=20spe?=
 =?UTF-8?q?cs?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 spec/oauth2/client_spec.rb | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/spec/oauth2/client_spec.rb b/spec/oauth2/client_spec.rb
index 85712f58..87b578ea 100644
--- a/spec/oauth2/client_spec.rb
+++ b/spec/oauth2/client_spec.rb
@@ -1,6 +1,5 @@
 # coding: utf-8
 
-require 'helper'
 require 'nkf'
 
 describe OAuth2::Client do
@@ -13,6 +12,7 @@
         stub.get('/unauthorized')        { |env| [401, {'Content-Type' => 'application/json'}, MultiJson.encode(:error => error_value, :error_description => error_description_value)] }
         stub.get('/conflict')            { |env| [409, {'Content-Type' => 'text/plain'}, 'not authorized'] }
         stub.get('/redirect')            { |env| [302, {'Content-Type' => 'text/plain', 'location' => '/success'}, ''] }
+        stub.get('/redirect_no_loc')     { |_env| [302, {'Content-Type' => 'text/plain'}, ''] }
         stub.post('/redirect')           { |env| [303, {'Content-Type' => 'text/plain', 'location' => '/reflect'}, ''] }
         stub.get('/error')               { |env| [500, {'Content-Type' => 'text/plain'}, 'unknown error'] }
         stub.get('/empty_get')           { |env| [204, {}, nil] }
@@ -24,6 +24,7 @@
 
   let!(:error_value) { 'invalid_token' }
   let!(:error_description_value) { 'bad bad token' }
+  let(:options) { {} }
 
   describe '#initialize' do
     it 'assigns id and secret' do
@@ -44,10 +45,10 @@
     end
 
     it 'is able to pass a block to configure the connection' do
-      connection = double('connection')
       builder = double('builder')
+
       allow(Faraday).to receive(:new).and_yield(builder)
-      allow(Faraday::Connection).to receive(:new).and_return(connection)
+      allow(builder).to receive(:response)
 
       expect(builder).to receive(:adapter).with(:test)
 
@@ -70,7 +71,7 @@
     it 'allows override of raise_errors option' do
       client = described_class.new('abc', 'def', :site => 'https://api.example.com', :raise_errors => true) do |builder|
         builder.adapter :test do |stub|
-          stub.get('/notfound') { |env| [404, {}, nil] }
+          stub.get('/notfound') { |_env| [404, {}, nil] }
         end
       end
       expect(client.options[:raise_errors]).to be true

From 233be800eb2e49a94df75d26bd531d23dbf27227 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Sat, 19 Feb 2022 03:46:03 +0700
Subject: [PATCH 109/163] =?UTF-8?q?=F0=9F=90=9B=20Backport=20fixes=20from?=
 =?UTF-8?q?=20#461=20&=20#469?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

- Add more specs

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 .rubocop_todo.yml          | 10 +++++-----
 lib/oauth2/client.rb       |  8 ++++----
 spec/oauth2/client_spec.rb | 26 +++++++++++++++++++++++++-
 3 files changed, 34 insertions(+), 10 deletions(-)

diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml
index 9168f954..e6fd754e 100644
--- a/.rubocop_todo.yml
+++ b/.rubocop_todo.yml
@@ -1,6 +1,6 @@
 # This configuration was generated by
 # `rubocop --auto-gen-config`
-# on 2022-02-18 17:51:21 UTC using RuboCop version 1.25.1.
+# on 2022-02-18 20:45:51 UTC using RuboCop version 1.25.1.
 # The point is for the user to remove these configuration records
 # one by one as the offenses are removed from the code base.
 # Note that changes in the inspected code, or installation of new
@@ -20,23 +20,23 @@ Lint/UselessAssignment:
     - '**/*.markdown'
     - 'spec/oauth2/client_spec.rb'
 
-# Offense count: 1
+# Offense count: 4
 # Configuration parameters: IgnoredMethods, CountRepeatedAttributes.
 Metrics/AbcSize:
   Max: 43
 
-# Offense count: 1
+# Offense count: 2
 # Configuration parameters: CountComments, CountAsOne, ExcludedMethods, IgnoredMethods.
 # IgnoredMethods: refine
 Metrics/BlockLength:
-  Max: 27
+  Max: 33
 
 # Offense count: 2
 # Configuration parameters: IgnoredMethods.
 Metrics/CyclomaticComplexity:
   Max: 11
 
-# Offense count: 7
+# Offense count: 8
 # Configuration parameters: CountComments, CountAsOne, ExcludedMethods, IgnoredMethods.
 Metrics/MethodLength:
   Max: 37
diff --git a/lib/oauth2/client.rb b/lib/oauth2/client.rb
index 500d5932..768e8042 100644
--- a/lib/oauth2/client.rb
+++ b/lib/oauth2/client.rb
@@ -20,8 +20,8 @@ class Client # rubocop:disable Metrics/ClassLength
     # @param [Hash] options the options to create the client with
     # @option options [String] :site the OAuth2 provider site host
     # @option options [String] :redirect_uri the absolute URI to the Redirection Endpoint for use in authorization grants and token exchange
-    # @option options [String] :authorize_url ('/oauth/authorize') absolute or relative URL path to the Authorization endpoint
-    # @option options [String] :token_url ('/oauth/token') absolute or relative URL path to the Token endpoint
+    # @option options [String] :authorize_url ('oauth/authorize') absolute or relative URL path to the Authorization endpoint
+    # @option options [String] :token_url ('oauth/token') absolute or relative URL path to the Token endpoint
     # @option options [Symbol] :token_method (:post) HTTP method to use to request token (:get or :post)
     # @option options [Symbol] :auth_scheme (:basic_auth) HTTP method to use to authorize request (:basic_auth or :request_body)
     # @option options [Hash] :connection_opts ({}) Hash of connection options to pass to initialize Faraday with
@@ -36,8 +36,8 @@ def initialize(client_id, client_secret, options = {}, &block)
       @secret = client_secret
       @site = opts.delete(:site)
       ssl = opts.delete(:ssl)
-      @options = {:authorize_url => '/oauth/authorize',
-                  :token_url => '/oauth/token',
+      @options = {:authorize_url => 'oauth/authorize',
+                  :token_url => 'oauth/token',
                   :token_method => :post,
                   :auth_scheme => :request_body,
                   :connection_opts => {},
diff --git a/spec/oauth2/client_spec.rb b/spec/oauth2/client_spec.rb
index 87b578ea..67b70c7d 100644
--- a/spec/oauth2/client_spec.rb
+++ b/spec/oauth2/client_spec.rb
@@ -4,7 +4,7 @@
 
 describe OAuth2::Client do
   subject do
-    described_class.new('abc', 'def', :site => 'https://api.example.com') do |builder|
+    described_class.new('abc', 'def', {:site => 'https://api.example.com'}.merge(options)) do |builder|
       builder.adapter :test do |stub|
         stub.get('/success')             { |env| [200, {'Content-Type' => 'text/awesome'}, 'yay'] }
         stub.get('/reflect')             { |env| [200, {}, env[:body]] }
@@ -110,6 +110,30 @@
         subject.options[:"#{url_type}_url"] = 'https://api.foo.com/oauth/custom'
         expect(subject.send("#{url_type}_url")).to eq('https://api.foo.com/oauth/custom')
       end
+
+      context 'when a URL with path is used in the site' do
+        let(:options) do
+          {:site => 'https://example.com/blog'}
+        end
+
+        it 'generates an authorization URL relative to the site' do
+          expect(subject.send("#{url_type}_url")).to eq("https://example.com/blog/oauth/#{url_type}")
+        end
+      end
+
+      context 'when a URL with path is used in the site and urls overridden' do
+        let(:options) do
+          {
+            :site => 'https://example.com/blog',
+            :authorize_url => "oauth/#{url_type}/lampoon",
+            :token_url => "oauth/#{url_type}/lampoon",
+          }
+        end
+
+        it 'generates an authorization URL relative to the site' do
+          expect(subject.send("#{url_type}_url")).to eq("https://example.com/blog/oauth/#{url_type}/lampoon")
+        end
+      end
     end
   end
 

From bf1c1006db5312f411516da535d5dbcac587721e Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Sat, 19 Feb 2022 04:02:18 +0700
Subject: [PATCH 110/163] =?UTF-8?q?=F0=9F=92=9A=20Only=20run=20code=20cove?=
 =?UTF-8?q?rage=20analysis=20in=20coverage=20workflow?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 .github/workflows/coverage.yml |  4 +++
 .simplecov                     | 55 +++++++++++++++++++++-------------
 spec/helper.rb                 |  7 +++--
 3 files changed, 42 insertions(+), 24 deletions(-)

diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml
index 5194c0f7..1ab6ced3 100644
--- a/.github/workflows/coverage.yml
+++ b/.github/workflows/coverage.yml
@@ -1,5 +1,9 @@
 name: Code Coverage
 
+env:
+  CI_CODECOV: true
+  COVER_ALL: true
+
 on:
   push:
     branches:
diff --git a/.simplecov b/.simplecov
index 829a7c6f..37858850 100644
--- a/.simplecov
+++ b/.simplecov
@@ -1,27 +1,40 @@
-SimpleCov.start do
-  enable_coverage :branch
-  primary_coverage :branch
+# To get coverage
+# On Local, default (HTML) output, it just works, coverage is turned on:
+#   bundle exec rspec spec
+# On Local, all output formats:
+#   COVER_ALL=true bundle exec rspec spec
+#
+# On CI, all output formats, the ENV variables CI is always set,
+#   and COVER_ALL, and CI_CODECOV, are set in the coverage.yml workflow only,
+#   so coverage only runs in that workflow, and outputs all formats.
+#
+RUN_COVERAGE = ENV['CI_CODECOV'] || ENV['CI'].nil?
+if RUN_COVERAGE
+  SimpleCov.start do
+    enable_coverage :branch
+    primary_coverage :branch
 
-  if ENV['CI'] || ENV['CODECOV']
-    require 'simplecov-lcov'
-    require 'simplecov-cobertura'
-    require 'coveralls'
+    if ENV['COVER_ALL']
+      require 'simplecov-lcov'
+      require 'simplecov-cobertura'
+      require 'coveralls'
 
-    SimpleCov::Formatter::LcovFormatter.config do |c|
-      c.report_with_single_file = true
-      c.single_report_path = 'coverage/lcov.info'
+      SimpleCov::Formatter::LcovFormatter.config do |c|
+        c.report_with_single_file = true
+        c.single_report_path = 'coverage/lcov.info'
+      end
+
+      SimpleCov.formatters = [
+        SimpleCov::Formatter::CoberturaFormatter,
+        SimpleCov::Formatter::HTMLFormatter,
+        SimpleCov::Formatter::LcovFormatter,
+        Coveralls::SimpleCov::Formatter,
+      ]
+    else
+      formatter SimpleCov::Formatter::HTMLFormatter
     end
 
-    SimpleCov.formatters = [
-      SimpleCov::Formatter::CoberturaFormatter,
-      SimpleCov::Formatter::HTMLFormatter,
-      SimpleCov::Formatter::LcovFormatter,
-      Coveralls::SimpleCov::Formatter,
-    ]
-  else
-    formatter SimpleCov::Formatter::HTMLFormatter
+    add_filter '/spec'
+    minimum_coverage(86)
   end
-
-  add_filter '/spec'
-  minimum_coverage(86)
 end
diff --git a/spec/helper.rb b/spec/helper.rb
index d62d71ee..414e229d 100644
--- a/spec/helper.rb
+++ b/spec/helper.rb
@@ -1,12 +1,13 @@
 DEBUG = ENV['DEBUG'] == 'true'
+RUN_COVERAGE = ENV['CI_CODECOV'] || ENV['CI'].nil?
 
 ruby_version = Gem::Version.new(RUBY_VERSION)
 minimum_version = ->(version) { ruby_version >= Gem::Version.new(version) && RUBY_ENGINE == 'ruby' }
-coverage = minimum_version.call('2.7')
-debug = minimum_version.call('2.5')
+coverage = minimum_version.call('2.7') && RUN_COVERAGE
+debug = minimum_version.call('2.5') && DEBUG
 
 require 'simplecov' if coverage
-require 'byebug' if DEBUG && debug
+require 'byebug' if debug
 
 require 'oauth2'
 require 'addressable/uri'

From 335bc0c8d1602731478d6f6a385c0a877be93095 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Sat, 19 Feb 2022 04:11:32 +0700
Subject: [PATCH 111/163] =?UTF-8?q?=E2=9E=96=20Coveralls=20not=20needed=20?=
 =?UTF-8?q?as=20a=20dependency?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

- Using github action instead, coverallsapp/github-action@master

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 .simplecov | 1 -
 Gemfile    | 1 -
 2 files changed, 2 deletions(-)

diff --git a/.simplecov b/.simplecov
index 37858850..69d229ee 100644
--- a/.simplecov
+++ b/.simplecov
@@ -17,7 +17,6 @@ if RUN_COVERAGE
     if ENV['COVER_ALL']
       require 'simplecov-lcov'
       require 'simplecov-cobertura'
-      require 'coveralls'
 
       SimpleCov::Formatter::LcovFormatter.config do |c|
         c.report_with_single_file = true
diff --git a/Gemfile b/Gemfile
index 07873599..f70db3da 100644
--- a/Gemfile
+++ b/Gemfile
@@ -30,7 +30,6 @@ platforms :mri do
     gem 'rubocop-thread_safety', '~> 0.4', :require => false
   end
   if coverage
-    gem 'coveralls_reborn', '~> 0.23', :require => false
     gem 'simplecov', '~> 0.21', :require => false
     gem 'simplecov-cobertura' # XML for Jenkins
     gem 'simplecov-lcov', '~> 0.8', :require => false

From 79c9e15076d2d0faaa801e29e72df098c5347ade Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Sat, 19 Feb 2022 04:51:41 +0700
Subject: [PATCH 112/163] =?UTF-8?q?=E2=9E=96=20Complete=20removal=20of=20c?=
 =?UTF-8?q?overals=20gem?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 .simplecov | 2 --
 1 file changed, 2 deletions(-)

diff --git a/.simplecov b/.simplecov
index 69d229ee..8170e552 100644
--- a/.simplecov
+++ b/.simplecov
@@ -8,7 +8,6 @@
 #   and COVER_ALL, and CI_CODECOV, are set in the coverage.yml workflow only,
 #   so coverage only runs in that workflow, and outputs all formats.
 #
-RUN_COVERAGE = ENV['CI_CODECOV'] || ENV['CI'].nil?
 if RUN_COVERAGE
   SimpleCov.start do
     enable_coverage :branch
@@ -27,7 +26,6 @@ if RUN_COVERAGE
         SimpleCov::Formatter::CoberturaFormatter,
         SimpleCov::Formatter::HTMLFormatter,
         SimpleCov::Formatter::LcovFormatter,
-        Coveralls::SimpleCov::Formatter,
       ]
     else
       formatter SimpleCov::Formatter::HTMLFormatter

From 0135d512dbd5cc51c6386e0eb6dd1fc2b7a4ddad Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Sat, 19 Feb 2022 05:08:59 +0700
Subject: [PATCH 113/163] =?UTF-8?q?=E2=9E=95=20Add=20codecov=20gem?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 .simplecov |  2 ++
 Gemfile    | 70 +++++++++++++++++++++++++++---------------------------
 2 files changed, 37 insertions(+), 35 deletions(-)

diff --git a/.simplecov b/.simplecov
index 8170e552..3e3c6a9c 100644
--- a/.simplecov
+++ b/.simplecov
@@ -14,6 +14,7 @@ if RUN_COVERAGE
     primary_coverage :branch
 
     if ENV['COVER_ALL']
+      require 'codecov'
       require 'simplecov-lcov'
       require 'simplecov-cobertura'
 
@@ -26,6 +27,7 @@ if RUN_COVERAGE
         SimpleCov::Formatter::CoberturaFormatter,
         SimpleCov::Formatter::HTMLFormatter,
         SimpleCov::Formatter::LcovFormatter,
+        SimpleCov::Formatter::Codecov,
       ]
     else
       formatter SimpleCov::Formatter::HTMLFormatter
diff --git a/Gemfile b/Gemfile
index f70db3da..1dbda68d 100644
--- a/Gemfile
+++ b/Gemfile
@@ -11,34 +11,41 @@ gem 'jwt'
 gem 'overcommit'
 gem 'rake'
 
-platforms :mri do
-  ruby_version = Gem::Version.new(RUBY_VERSION)
-  minimum_version = ->(version) { ruby_version >= Gem::Version.new(version) && RUBY_ENGINE == 'ruby' }
-  linting = minimum_version.call('2.7')
-  coverage = minimum_version.call('2.7')
-  debug = minimum_version.call('2.5')
-  if linting
-    # Danger is incompatible with Faraday 2 (for now)
-    # see: https://github.com/danger/danger/issues/1349
-    # gem 'danger', '~> 8.4'
-    gem 'rubocop', '~> 1.22', :require => false
-    gem 'rubocop-md', '~> 1.0', :require => false
-    gem 'rubocop-packaging', '~> 0.5', :require => false
-    gem 'rubocop-performance', '~> 1.11', :require => false
-    gem 'rubocop-rake', '~> 0.6', :require => false
-    gem 'rubocop-rspec', :require => false
-    gem 'rubocop-thread_safety', '~> 0.4', :require => false
-  end
-  if coverage
-    gem 'simplecov', '~> 0.21', :require => false
-    gem 'simplecov-cobertura' # XML for Jenkins
-    gem 'simplecov-lcov', '~> 0.8', :require => false
-  end
-  if debug
-    # No need to run byebug / pry on earlier versions
-    gem 'byebug'
-    gem 'pry'
-    gem 'pry-byebug'
+group :test do
+  gem 'addressable', '~> 2.3.8'
+  gem 'backports'
+  gem 'rack', '~> 1.2', :platforms => [:ruby_21]
+  gem 'rspec', '>= 3'
+  platforms :mri do
+    ruby_version = Gem::Version.new(RUBY_VERSION)
+    minimum_version = ->(version) { ruby_version >= Gem::Version.new(version) && RUBY_ENGINE == 'ruby' }
+    linting = minimum_version.call('2.7')
+    coverage = minimum_version.call('2.7')
+    debug = minimum_version.call('2.5')
+    if linting
+      # Danger is incompatible with Faraday 2 (for now)
+      # see: https://github.com/danger/danger/issues/1349
+      # gem 'danger', '~> 8.4'
+      gem 'rubocop', '~> 1.22', :require => false
+      gem 'rubocop-md', '~> 1.0', :require => false
+      gem 'rubocop-packaging', '~> 0.5', :require => false
+      gem 'rubocop-performance', '~> 1.11', :require => false
+      gem 'rubocop-rake', '~> 0.6', :require => false
+      gem 'rubocop-rspec', :require => false
+      gem 'rubocop-thread_safety', '~> 0.4', :require => false
+    end
+    if coverage
+      gem 'codecov', :require => false, :group => :test
+      gem 'simplecov', '~> 0.21', :require => false
+      gem 'simplecov-cobertura' # XML for Jenkins
+      gem 'simplecov-lcov', '~> 0.8', :require => false
+    end
+    if debug
+      # No need to run byebug / pry on earlier versions
+      gem 'byebug'
+      gem 'pry'
+      gem 'pry-byebug'
+    end
   end
 end
 
@@ -48,10 +55,3 @@ group :documentation do
   gem 'redcarpet', :platform => :mri
   gem 'yard', :require => false
 end
-
-group :test do
-  gem 'addressable', '~> 2.3.8'
-  gem 'backports'
-  gem 'rack', '~> 1.2', :platforms => [:ruby_21]
-  gem 'rspec', '>= 3'
-end

From 88dc325c0ab4c73aed7e8e60556e884b21f949a8 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Sat, 19 Feb 2022 05:14:47 +0700
Subject: [PATCH 114/163] =?UTF-8?q?=F0=9F=92=9A=20Passing=20branch=20code?=
 =?UTF-8?q?=20coverage=20at=2085%?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 .github/workflows/coverage.yml | 19 ++++++++++---------
 .simplecov                     |  2 +-
 2 files changed, 11 insertions(+), 10 deletions(-)

diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml
index 1ab6ced3..0ab4371a 100644
--- a/.github/workflows/coverage.yml
+++ b/.github/workflows/coverage.yml
@@ -109,12 +109,13 @@ jobs:
           github-token: ${{ secrets.GITHUB_TOKEN }}
         continue-on-error: ${{ matrix.experimental != 'false' }}
 
-      - name: CodeCov
-        uses: codecov/codecov-action@v2
-        if: matrix.ruby == '2.7' && github.event_name != 'pull_request' && always()
-        with:
-          files: ./coverage/coverage.xml
-          flags: unittests
-          name: codecov-upload
-          fail_ci_if_error: true
-        continue-on-error: ${{ matrix.experimental != 'false' }}
+#      Using the codecov gem instead.
+#      - name: CodeCov
+#        uses: codecov/codecov-action@v2
+#        if: matrix.ruby == '2.7' && github.event_name != 'pull_request' && always()
+#        with:
+#          files: ./coverage/coverage.xml
+#          flags: unittests
+#          name: codecov-upload
+#          fail_ci_if_error: true
+#        continue-on-error: ${{ matrix.experimental != 'false' }}
diff --git a/.simplecov b/.simplecov
index 3e3c6a9c..a36a7c57 100644
--- a/.simplecov
+++ b/.simplecov
@@ -34,6 +34,6 @@ if RUN_COVERAGE
     end
 
     add_filter '/spec'
-    minimum_coverage(86)
+    minimum_coverage(85)
   end
 end

From 5d73923fc7d09d19915275771bb3cc8f70c3ccc3 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Sat, 19 Feb 2022 05:57:39 +0700
Subject: [PATCH 115/163] =?UTF-8?q?=E2=9C=8F=EF=B8=8F=20Fix=20all=20IETF?=
 =?UTF-8?q?=20Links?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 lib/oauth2/authenticator.rb               |  2 +-
 lib/oauth2/client.rb                      | 16 ++++++++--------
 lib/oauth2/strategy/assertion.rb          |  2 +-
 lib/oauth2/strategy/auth_code.rb          |  2 +-
 lib/oauth2/strategy/client_credentials.rb |  2 +-
 lib/oauth2/strategy/implicit.rb           |  2 +-
 lib/oauth2/strategy/password.rb           |  2 +-
 7 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/lib/oauth2/authenticator.rb b/lib/oauth2/authenticator.rb
index 9588da34..48158072 100644
--- a/lib/oauth2/authenticator.rb
+++ b/lib/oauth2/authenticator.rb
@@ -60,7 +60,7 @@ def apply_basic_auth(params)
       params.merge(:headers => headers)
     end
 
-    # @see https://tools.ietf.org/html/rfc2617#section-2
+    # @see https://datatracker.ietf.org/doc/html/rfc2617#section-2
     def basic_auth_header
       {'Authorization' => self.class.encode_basic_auth(id, secret)}
     end
diff --git a/lib/oauth2/client.rb b/lib/oauth2/client.rb
index 768e8042..88aa5d4e 100644
--- a/lib/oauth2/client.rb
+++ b/lib/oauth2/client.rb
@@ -197,28 +197,28 @@ def get_token(params, access_token_opts = {}, extract_access_token = options[:ex
 
     # The Authorization Code strategy
     #
-    # @see http://tools.ietf.org/html/draft-ietf-oauth-v2-15#section-4.1
+    # @see http://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-15#section-4.1
     def auth_code
       @auth_code ||= OAuth2::Strategy::AuthCode.new(self)
     end
 
     # The Implicit strategy
     #
-    # @see http://tools.ietf.org/html/draft-ietf-oauth-v2-26#section-4.2
+    # @see http://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-26#section-4.2
     def implicit
       @implicit ||= OAuth2::Strategy::Implicit.new(self)
     end
 
     # The Resource Owner Password Credentials strategy
     #
-    # @see http://tools.ietf.org/html/draft-ietf-oauth-v2-15#section-4.3
+    # @see http://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-15#section-4.3
     def password
       @password ||= OAuth2::Strategy::Password.new(self)
     end
 
     # The Client Credentials strategy
     #
-    # @see http://tools.ietf.org/html/draft-ietf-oauth-v2-15#section-4.4
+    # @see http://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-15#section-4.4
     def client_credentials
       @client_credentials ||= OAuth2::Strategy::ClientCredentials.new(self)
     end
@@ -238,10 +238,10 @@ def assertion
     #
     # @api semipublic
     #
-    # @see https://tools.ietf.org/html/rfc6749#section-4.1
-    # @see https://tools.ietf.org/html/rfc6749#section-4.1.3
-    # @see https://tools.ietf.org/html/rfc6749#section-4.2.1
-    # @see https://tools.ietf.org/html/rfc6749#section-10.6
+    # @see https://datatracker.ietf.org/doc/html/rfc6749#section-4.1
+    # @see https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.3
+    # @see https://datatracker.ietf.org/doc/html/rfc6749#section-4.2.1
+    # @see https://datatracker.ietf.org/doc/html/rfc6749#section-10.6
     # @return [Hash] the params to add to a request or URL
     def redirection_params
       if options[:redirect_uri]
diff --git a/lib/oauth2/strategy/assertion.rb b/lib/oauth2/strategy/assertion.rb
index 8dc27b50..1ea8415c 100644
--- a/lib/oauth2/strategy/assertion.rb
+++ b/lib/oauth2/strategy/assertion.rb
@@ -4,7 +4,7 @@ module OAuth2
   module Strategy
     # The Client Assertion Strategy
     #
-    # @see http://tools.ietf.org/html/draft-ietf-oauth-v2-10#section-4.1.3
+    # @see https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-10#section-4.1.3
     #
     # Sample usage:
     #   client = OAuth2::Client.new(client_id, client_secret,
diff --git a/lib/oauth2/strategy/auth_code.rb b/lib/oauth2/strategy/auth_code.rb
index 76f92aa9..dff92922 100644
--- a/lib/oauth2/strategy/auth_code.rb
+++ b/lib/oauth2/strategy/auth_code.rb
@@ -2,7 +2,7 @@ module OAuth2
   module Strategy
     # The Authorization Code Strategy
     #
-    # @see http://tools.ietf.org/html/draft-ietf-oauth-v2-15#section-4.1
+    # @see http://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-15#section-4.1
     class AuthCode < Base
       # The required query parameters for the authorize URL
       #
diff --git a/lib/oauth2/strategy/client_credentials.rb b/lib/oauth2/strategy/client_credentials.rb
index 35ac5fd8..cfcecd56 100644
--- a/lib/oauth2/strategy/client_credentials.rb
+++ b/lib/oauth2/strategy/client_credentials.rb
@@ -2,7 +2,7 @@ module OAuth2
   module Strategy
     # The Client Credentials Strategy
     #
-    # @see http://tools.ietf.org/html/draft-ietf-oauth-v2-15#section-4.4
+    # @see http://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-15#section-4.4
     class ClientCredentials < Base
       # Not used for this strategy
       #
diff --git a/lib/oauth2/strategy/implicit.rb b/lib/oauth2/strategy/implicit.rb
index 6ab505db..15e99c07 100644
--- a/lib/oauth2/strategy/implicit.rb
+++ b/lib/oauth2/strategy/implicit.rb
@@ -2,7 +2,7 @@ module OAuth2
   module Strategy
     # The Implicit Strategy
     #
-    # @see http://tools.ietf.org/html/draft-ietf-oauth-v2-26#section-4.2
+    # @see http://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-26#section-4.2
     class Implicit < Base
       # The required query parameters for the authorize URL
       #
diff --git a/lib/oauth2/strategy/password.rb b/lib/oauth2/strategy/password.rb
index 075dec51..a6498cd3 100644
--- a/lib/oauth2/strategy/password.rb
+++ b/lib/oauth2/strategy/password.rb
@@ -2,7 +2,7 @@ module OAuth2
   module Strategy
     # The Resource Owner Password Credentials Authorization Strategy
     #
-    # @see http://tools.ietf.org/html/draft-ietf-oauth-v2-15#section-4.3
+    # @see http://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-15#section-4.3
     class Password < Base
       # Not used for this strategy
       #

From 1e4755e56ac479c2ac0aeeda81f8d8e621f4ac20 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Sat, 19 Feb 2022 06:47:23 +0700
Subject: [PATCH 116/163] =?UTF-8?q?=E2=9C=85=20Properly=20test=20Assertion?=
 =?UTF-8?q?s?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

- https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-10#section-4.1.3

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 spec/fixtures/README.md                | 11 ++++
 spec/fixtures/RS256/jwtRS256.key       | 51 ++++++++++++++++
 spec/fixtures/RS256/jwtRS256.key.pub   | 14 +++++
 spec/oauth2/strategy/assertion_spec.rb | 84 +++++++++++++++++++++-----
 4 files changed, 144 insertions(+), 16 deletions(-)
 create mode 100644 spec/fixtures/README.md
 create mode 100644 spec/fixtures/RS256/jwtRS256.key
 create mode 100644 spec/fixtures/RS256/jwtRS256.key.pub

diff --git a/spec/fixtures/README.md b/spec/fixtures/README.md
new file mode 100644
index 00000000..e8ed536a
--- /dev/null
+++ b/spec/fixtures/README.md
@@ -0,0 +1,11 @@
+# RS256
+
+## How keys were made
+
+```shell
+# No passphrase
+# Generates the public and private keys:
+ssh-keygen -t rsa -b 4096 -m PEM -f jwtRS256.key
+# Converts the key to PEM format
+openssl rsa -in jwtRS256.key -pubout -outform PEM -out jwtRS256.key.pub
+```
diff --git a/spec/fixtures/RS256/jwtRS256.key b/spec/fixtures/RS256/jwtRS256.key
new file mode 100644
index 00000000..72005e50
--- /dev/null
+++ b/spec/fixtures/RS256/jwtRS256.key
@@ -0,0 +1,51 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIJKwIBAAKCAgEA5hdXV/4YSymY1T9VNvK2bWRfulwIty1RnAPNINQmfh3aRRkV
++PNrbC2Crji9G0AHmQwgW1bZ3kgkkpIm6RVn44fHvBvuXkZ9ABgXw0d2cLIHmwOF
+xSKmWAm/EW//GszUTLLLsMZUe2udtFJW0jxXB2GRY0WVYuo6Oo58RCeP719lw3Ag
+s0YF9/IobxKkGd4BautUPw6ZszAa3o+j0zR74x7ouPxybZAOuPsMxqanyeYJeH4o
+sJjLMYV9qem9uG2sj7GENJ8UszcpmGbqxBhexPEB7mgDeONIF0XJF23zdOf8ANE5
+mAU2h2v7M6moAfkdUzJ+j48+VT2omHAzAL5yNcmrl2xiWdyoxOw1Y1UmfEmJYV5V
+gGYyZ12JZRKY+szPT+vR+MDuYxbquF40O7kvkFNBfL1yCpzfSQCLnEs4rX8qRzZX
+ciLeyq4Ht5FLuRFgxjA//XI8LAmp0u7gk+Q7FUH1UgW3kmJDTG0XaxQxYTBSIO7m
+cmyjDyBgKVuQmt5E1ycFeteOVdPD/CG/fPYhthvc4UytEFwsMdNy3iD6/wuUH68t
+AKam28UZaOb0qK+00cQQD8fulY9rKtSL10LvJFWUOa/SJyLvk9vUmfvFn182il1n
+X6GpyxyMmE/FCnH4CT/DjrSZf08mOO8eL5ofYHMK/oiXr1eODqx+pOwClNsCAwEA
+AQKCAgEAy34vMFI4WBk04rx9d/hWoQ7Znu8QgjihaZLvEy6t0HJEfUH/bcqS4fyq
+C72Aeh452gCgiUeZrf4t4jdCFHhrBg8q9dHaEiTTHocwVPPZ6zd4hH8sCrpnVYth
+IWHkw2YOCLtEbFYrl3AI7Na5lHvrGEsREzQSN4Yh83Has0guAy1iyeNb+FFgq/XO
+DtX0ri/rHw1717zo8FIGIXn2EK/lNWw7tIcICKAUdUMK/JGd6XD6RUeGYxDu/CAs
+kF55/Sd6Kyd7XjKnUwzhS7kRvlYzUog4BgqVr4+LTZHZlFAYtfcJqAtinXFW1ZQJ
+eZp9TSlt5wvMZNjx7t92QUNRyEGmrQAU+8COHnT0/drFf0MCiyHSUN0E7/5fswhc
+uMSU9XiJA9G0wYvJl4zIuOuIYWZWhIqvjYSkvdlP70t9XO2gk/ZcCWsMW8i+xbwC
+w1+MMjsKsNedXxI99TIPPHcCNMxqlt1E1kHH3SAwCuEH/ez7PRMyEQQ0EyAk22x/
+piYIWXkX5835cLbLRIYafXgOiugWZjCwIqfRIcIpscmcijZwCF2DyevveYdx3krR
+FGA2PFydFyxCNG7XwvKb9kHb7WBERUPV/H3eCqu2SZ/RvF+I94LUYP4bu6CmFdO9
+wCJcGJoL1P7tVhS9lA5Oj0QWczrjnejCoI9XMMduWk032rR1VYECggEBAPZDnTBY
+H2uiVmGdMfWTAmX86kiHVpkL03OG6rgvDMsMOYKnik9Lb3gNeUIuPeAWFNrXCoD1
+qp0loxPhKSojNOOM8Yiz/GwQ/QI9dzgtxs7E7rFFyTuJcY48Do8uOFyUHbAbeOBF
+b9UL/uBfWZGVV1YY753xyqYlCpxTVQGms1jsbVFdZE1iVpOwAkFVuoLYaHLut4zB
+01ORyBSoWan173P+IQH6F1uNXE2Kk/FIMDN6bgP1pXkdkrTx4WjAmRnP/Sc4r38/
+F1xN+gxnWGPUKDVRPYBpVzDR036w65ODgg2FROK2vIxlStiAC/rc0JLsvaWfb1Rn
+dsWdJJ1V6mZ6a5sCggEBAO8wC1jcIoiBz3xoA8E5BSt8qLJ7ZuSFaaidvWX2/xj6
+lSWJxCGQfhR7P6ozvH6UDo1WbJT6nNyXPkiDkAzcmAdsYVjULW3K2LI9oPajaJxY
+L7KJpylgh9JhMvbMz3VVjTgYRt+kjX+3uFMZNx1YfiBP+S6xx5sjK9CKDz3H99kC
+q9bX95YFqZ7yFE3aBCR6CENo2tXpMN96CLQGpwa0bwt3xNzC4MhZMXbGR3DdBYbD
+tS9lJfQvAVUYxbSE/2FBgjpO6ArMyU2ZUEDFx9J6IhfhVbQV4VeITMyRNo0XwBiQ
+/+XpLXgHkw7LiNMIoc7d+M7yLA1Vz7+r8XxWHHZCL8ECggEBAPK8VrYORno7e1Wg
+MlxS2WxZzTxMWmlkpLoc5END7SI/HHjSV5wtSORWs40uM0MrwMasa+gNPmzDamjv
+6Tllln4ssO8EKe0DGcAZgefYBzxMFNKbbOzIXyvJurga4Ocv/8tUaOL2znJ67nGO
+yqSbRYjR724JpKv7mufXo9SK0gD2mhI3MeSs55WPScnIjJzoXpva/QU7D+gxq7vg
+7PCAP9RfS329W0Sco7yyuXx8oTY8mTBB8ybcpXzBZmNwY/hzcJ42W5XbRFVxbuTH
+APL1beSP/UUTkCPIzuTz0mCGoaxeDjZB1Lu2I/4eyLAu80+/FneoHX5etU23xR1o
+UDFOvb0CggEBALTTc6CoPAtLaBs7X6tSelAYHEli9bTKD8kEB83wX4b42ozYjEh7
+vnWpf8Yi+twO/rlnnws6NCCoztNvcxXmJ6FlFGtdbULV2eFWqjwL6ehY2yZ03sVv
+Tv+DsE3ZJPYlyW+hGuO0uazWrilUpNAwuJmhHFdq2+azPkqYNVGVvhB37oWsHGd0
+vHmHtkXtDris8VZVDSwu8V3iGnZPmTJ+cn0O/OuRAPM2SyjqWdQ/pA/wIShFpd3n
+M3CsG7uP2KokJloCkXaov39E6uEtJRZAc0nudyaAbC4Kw1Tca4tba0SnSm78S/20
+bD8BLN2uZvXH5nQ9rYQfXcIgMZ64UygsfYECggEBAIw0fQaIVmafa0Hz3ipD4PJI
+5QNkh2t9hvOCSKm1xYTNATl0q/VIkZoy1WoxY6SSchcObLxQKbJ9ORi4XNr+IJK5
+3C1Qz/3iv/S3/ktgmqGhQiqybkkHZcbqTXB2wxrx+aaLS7PEfYiuYCrPbX93160k
+MVns8PjvYU8KCNMbL2e+AiKEt1KkKAZIpNQdeeJOEhV9wuLYFosd400aYssuSOVW
+IkJhGI0lT/7FDJaw0LV98DhQtauANPSUQKN5iw6vciwtsaF1kXMfGlMXj58ntiMq
+NizQPR6/Ar1ewLPMh1exDoAfLnCIMk8nbSraW+cebLAZctPugUpfpu3j2LM98aE=
+-----END RSA PRIVATE KEY-----
diff --git a/spec/fixtures/RS256/jwtRS256.key.pub b/spec/fixtures/RS256/jwtRS256.key.pub
new file mode 100644
index 00000000..1a2f63d1
--- /dev/null
+++ b/spec/fixtures/RS256/jwtRS256.key.pub
@@ -0,0 +1,14 @@
+-----BEGIN PUBLIC KEY-----
+MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA5hdXV/4YSymY1T9VNvK2
+bWRfulwIty1RnAPNINQmfh3aRRkV+PNrbC2Crji9G0AHmQwgW1bZ3kgkkpIm6RVn
+44fHvBvuXkZ9ABgXw0d2cLIHmwOFxSKmWAm/EW//GszUTLLLsMZUe2udtFJW0jxX
+B2GRY0WVYuo6Oo58RCeP719lw3Ags0YF9/IobxKkGd4BautUPw6ZszAa3o+j0zR7
+4x7ouPxybZAOuPsMxqanyeYJeH4osJjLMYV9qem9uG2sj7GENJ8UszcpmGbqxBhe
+xPEB7mgDeONIF0XJF23zdOf8ANE5mAU2h2v7M6moAfkdUzJ+j48+VT2omHAzAL5y
+Ncmrl2xiWdyoxOw1Y1UmfEmJYV5VgGYyZ12JZRKY+szPT+vR+MDuYxbquF40O7kv
+kFNBfL1yCpzfSQCLnEs4rX8qRzZXciLeyq4Ht5FLuRFgxjA//XI8LAmp0u7gk+Q7
+FUH1UgW3kmJDTG0XaxQxYTBSIO7mcmyjDyBgKVuQmt5E1ycFeteOVdPD/CG/fPYh
+thvc4UytEFwsMdNy3iD6/wuUH68tAKam28UZaOb0qK+00cQQD8fulY9rKtSL10Lv
+JFWUOa/SJyLvk9vUmfvFn182il1nX6GpyxyMmE/FCnH4CT/DjrSZf08mOO8eL5of
+YHMK/oiXr1eODqx+pOwClNsCAwEAAQ==
+-----END PUBLIC KEY-----
diff --git a/spec/oauth2/strategy/assertion_spec.rb b/spec/oauth2/strategy/assertion_spec.rb
index ea1436e8..b2950c1a 100644
--- a/spec/oauth2/strategy/assertion_spec.rb
+++ b/spec/oauth2/strategy/assertion_spec.rb
@@ -1,5 +1,7 @@
+require 'openssl'
+
 describe OAuth2::Strategy::Assertion do
-  subject { client.assertion }
+  let(:client_assertion) { client.assertion }
 
   let(:client) do
     cli = OAuth2::Client.new('abc', 'def', :site => 'http://api.example.com')
@@ -28,31 +30,81 @@
 
   describe '#authorize_url' do
     it 'raises NotImplementedError' do
-      expect { subject.authorize_url }.to raise_error(NotImplementedError)
+      expect { client_assertion.authorize_url }.to raise_error(NotImplementedError)
     end
   end
 
   %w[json formencoded].each do |mode|
-    describe "#get_token (#{mode})" do
-      before do
-        @mode = mode
-        @access = subject.get_token(params)
-      end
+    before { @mode = mode }
 
-      it 'returns AccessToken with same Client' do
-        expect(@access.client).to eq(client)
-      end
+    shared_examples_for "get_token #{mode}" do
+      describe "#get_token (#{mode})" do
+        subject(:get_token) { client_assertion.get_token(params) }
 
-      it 'returns AccessToken with #token' do
-        expect(@access.token).to eq('salmon')
+        it 'returns AccessToken with same Client' do
+          expect(get_token.client).to eq(client)
+        end
+
+        it 'returns AccessToken with #token' do
+          expect(get_token.token).to eq('salmon')
+        end
+
+        it 'returns AccessToken with #expires_in' do
+          expect(get_token.expires_in).to eq(600)
+        end
+
+        it 'returns AccessToken with #expires_at' do
+          expect(get_token.expires_at).not_to be_nil
+        end
       end
+    end
 
-      it 'returns AccessToken with #expires_in' do
-        expect(@access.expires_in).to eq(600)
+    it_behaves_like "get_token #{mode}"
+    describe "#build_assertion (#{mode})" do
+      context "with hmac_secret" do
+        let(:hmac_secret) { '1883be842495c3b58f68ca71fbf1397fbb9ed2fdf8990f8404a25d0a1b995943' }
+        let(:params) do
+          {
+            :iss => 2345,
+            :aud => "too",
+            :prn => "much",
+            :exp => 123456789,
+            :hmac_secret => hmac_secret,
+          }
+        end
+        let(:jwt) { 'eyJhbGciOiJIUzI1NiJ9.eyJpc3MiOjIzNDUsImF1ZCI6InRvbyIsInBybiI6Im11Y2giLCJleHAiOjEyMzQ1Njc4OX0.GnZjgcdc5WSWKNW0p9S4GuhpBs3LJCEqjPm6turLG-c' }
+
+        subject(:build_assertion) { client_assertion.build_assertion(params) }
+
+        it 'returns JWT' do
+          expect(build_assertion).to eq(jwt)
+        end
+
+        it_behaves_like "get_token #{mode}"
       end
 
-      it 'returns AccessToken with #expires_at' do
-        expect(@access.expires_at).not_to be_nil
+      context "with private_key" do
+        let(:private_key_file) { 'spec/fixtures/RS256/jwtRS256.key' }
+        let(:password) { '' }
+        let(:private_key) { OpenSSL::PKey::RSA.new(File.read(private_key_file), password) }
+        let(:params) do
+          {
+            :iss => 2345,
+            :aud => "too",
+            :prn => "much",
+            :exp => 123456789,
+            :private_key => private_key,
+          }
+        end
+        let(:jwt) { 'eyJhbGciOiJSUzI1NiJ9.eyJpc3MiOjIzNDUsImF1ZCI6InRvbyIsInBybiI6Im11Y2giLCJleHAiOjEyMzQ1Njc4OX0.vJ32OiPVMdJrlNkPw02Y9u6beiFY0Mfndhg_CkEDLtOYn8dscQIEpWoR4GzH8tiQVOQ1fOkqxE95tNIKOTjnIoskmYnfzhzIl9fnfQ_lsEuLC-nq45KhPzSM2wYgF2ZEIjDq51daK70bRPzTBr1Id45cTY-jJSito0lbKXj2nPa_Gs-_vyEU2MSxjiMaIxxccfY4Ow5zN3AUMTKp6LjrpDKFxag3fJ1nrb6iDATa504gyJHVLift3ovhAwYidkA81WnmEtISWBY904CKIcZD9Cx3ifS5bc3JaLAteIBKAAyD8o7D60vOKutsjCMHUCKL357BQ36bW7fmaEtW367Ri-xgOsCY0_HeWp991vrJ-DxhFPeuF-8hn_9KggBzKbA2eKEOOY4iDKSFwjWQUFOcRdvHw9RgbGt0IjY3wdo8CaJVlhynh54YlaLgOFhTBPeMgZdqQUHOztljaK9zubeVkrDGNnGuSuq0KR82KArb1x2z7XyZpxiV5ZatP9SNyhn-YIWk7UeQYXaS0UfsBX7L5T1y_FZj84r7Vl42lj1DfdR5DyGvHfZyHotTnejdIrDuQfDL_bGe24eHsilzuEFaajYmu10hxflZ6Apm-lekRRV47tbxTF1zI5we14XsTeklrTXqgDkSw6gyOoNUJm-cQkJpfdvBgUHYGInC1ttz7NU' }
+
+        subject(:build_assertion) { client_assertion.build_assertion(params) }
+
+        it 'returns JWT' do
+          expect(build_assertion).to eq(jwt)
+        end
+
+        it_behaves_like "get_token #{mode}"
       end
     end
   end

From 2a8be17516872f51e877d1f0eadff6459c05e85c Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Sat, 19 Feb 2022 06:52:58 +0700
Subject: [PATCH 117/163] =?UTF-8?q?=F0=9F=9A=A8=20Lint=20fixes?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 .rubocop_todo.yml                      |  6 +++---
 spec/oauth2/strategy/assertion_spec.rb | 24 ++++++++++++------------
 2 files changed, 15 insertions(+), 15 deletions(-)

diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml
index e6fd754e..0be291e3 100644
--- a/.rubocop_todo.yml
+++ b/.rubocop_todo.yml
@@ -1,6 +1,6 @@
 # This configuration was generated by
 # `rubocop --auto-gen-config`
-# on 2022-02-18 20:45:51 UTC using RuboCop version 1.25.1.
+# on 2022-02-18 23:52:28 UTC using RuboCop version 1.25.1.
 # The point is for the user to remove these configuration records
 # one by one as the offenses are removed from the code base.
 # Note that changes in the inspected code, or installation of new
@@ -25,11 +25,11 @@ Lint/UselessAssignment:
 Metrics/AbcSize:
   Max: 43
 
-# Offense count: 2
+# Offense count: 4
 # Configuration parameters: CountComments, CountAsOne, ExcludedMethods, IgnoredMethods.
 # IgnoredMethods: refine
 Metrics/BlockLength:
-  Max: 33
+  Max: 59
 
 # Offense count: 2
 # Configuration parameters: IgnoredMethods.
diff --git a/spec/oauth2/strategy/assertion_spec.rb b/spec/oauth2/strategy/assertion_spec.rb
index b2950c1a..bd05b2c6 100644
--- a/spec/oauth2/strategy/assertion_spec.rb
+++ b/spec/oauth2/strategy/assertion_spec.rb
@@ -61,21 +61,21 @@
 
     it_behaves_like "get_token #{mode}"
     describe "#build_assertion (#{mode})" do
-      context "with hmac_secret" do
+      context 'with hmac_secret' do
+        subject(:build_assertion) { client_assertion.build_assertion(params) }
+
         let(:hmac_secret) { '1883be842495c3b58f68ca71fbf1397fbb9ed2fdf8990f8404a25d0a1b995943' }
         let(:params) do
           {
             :iss => 2345,
-            :aud => "too",
-            :prn => "much",
-            :exp => 123456789,
+            :aud => 'too',
+            :prn => 'much',
+            :exp => 123_456_789,
             :hmac_secret => hmac_secret,
           }
         end
         let(:jwt) { 'eyJhbGciOiJIUzI1NiJ9.eyJpc3MiOjIzNDUsImF1ZCI6InRvbyIsInBybiI6Im11Y2giLCJleHAiOjEyMzQ1Njc4OX0.GnZjgcdc5WSWKNW0p9S4GuhpBs3LJCEqjPm6turLG-c' }
 
-        subject(:build_assertion) { client_assertion.build_assertion(params) }
-
         it 'returns JWT' do
           expect(build_assertion).to eq(jwt)
         end
@@ -83,23 +83,23 @@
         it_behaves_like "get_token #{mode}"
       end
 
-      context "with private_key" do
+      context 'with private_key' do
+        subject(:build_assertion) { client_assertion.build_assertion(params) }
+
         let(:private_key_file) { 'spec/fixtures/RS256/jwtRS256.key' }
         let(:password) { '' }
         let(:private_key) { OpenSSL::PKey::RSA.new(File.read(private_key_file), password) }
         let(:params) do
           {
             :iss => 2345,
-            :aud => "too",
-            :prn => "much",
-            :exp => 123456789,
+            :aud => 'too',
+            :prn => 'much',
+            :exp => 123_456_789,
             :private_key => private_key,
           }
         end
         let(:jwt) { 'eyJhbGciOiJSUzI1NiJ9.eyJpc3MiOjIzNDUsImF1ZCI6InRvbyIsInBybiI6Im11Y2giLCJleHAiOjEyMzQ1Njc4OX0.vJ32OiPVMdJrlNkPw02Y9u6beiFY0Mfndhg_CkEDLtOYn8dscQIEpWoR4GzH8tiQVOQ1fOkqxE95tNIKOTjnIoskmYnfzhzIl9fnfQ_lsEuLC-nq45KhPzSM2wYgF2ZEIjDq51daK70bRPzTBr1Id45cTY-jJSito0lbKXj2nPa_Gs-_vyEU2MSxjiMaIxxccfY4Ow5zN3AUMTKp6LjrpDKFxag3fJ1nrb6iDATa504gyJHVLift3ovhAwYidkA81WnmEtISWBY904CKIcZD9Cx3ifS5bc3JaLAteIBKAAyD8o7D60vOKutsjCMHUCKL357BQ36bW7fmaEtW367Ri-xgOsCY0_HeWp991vrJ-DxhFPeuF-8hn_9KggBzKbA2eKEOOY4iDKSFwjWQUFOcRdvHw9RgbGt0IjY3wdo8CaJVlhynh54YlaLgOFhTBPeMgZdqQUHOztljaK9zubeVkrDGNnGuSuq0KR82KArb1x2z7XyZpxiV5ZatP9SNyhn-YIWk7UeQYXaS0UfsBX7L5T1y_FZj84r7Vl42lj1DfdR5DyGvHfZyHotTnejdIrDuQfDL_bGe24eHsilzuEFaajYmu10hxflZ6Apm-lekRRV47tbxTF1zI5we14XsTeklrTXqgDkSw6gyOoNUJm-cQkJpfdvBgUHYGInC1ttz7NU' }
 
-        subject(:build_assertion) { client_assertion.build_assertion(params) }
-
         it 'returns JWT' do
           expect(build_assertion).to eq(jwt)
         end

From 47b6963a866442fd64e6ede90fc5cbbfb96b5d1c Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Sun, 20 Feb 2022 00:50:49 -0700
Subject: [PATCH 118/163] Faraday version test matrix (#573)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* ✨ Test Matrix for Faraday v0, v1, v2

Signed-off-by: Peter Boling <peter.boling@gmail.com>

* 🚨 Lint Style/FrozenStringLiteralComment Fixes

Signed-off-by: Peter Boling <peter.boling@gmail.com>

* 👷 Fix Faraday Gemfiles for build

Signed-off-by: Peter Boling <peter.boling@gmail.com>

* 👷 Add source to Faraday Gemfiles

Signed-off-by: Peter Boling <peter.boling@gmail.com>

* 👷 Improved naming of workflow jobs

Signed-off-by: Peter Boling <peter.boling@gmail.com>

* 👷 Fix workflow job exclusions

Signed-off-by: Peter Boling <peter.boling@gmail.com>

* 👷 Fix workflow job exclusions

Signed-off-by: Peter Boling <peter.boling@gmail.com>

* 👷 Builds for MacOS, Windows, and Ancient Ubuntu 18.04

Signed-off-by: Peter Boling <peter.boling@gmail.com>

* 👷 Fix matrix for ancient build

Signed-off-by: Peter Boling <peter.boling@gmail.com>

* 👷 Fix matrix for MacOS and Windows builds

Signed-off-by: Peter Boling <peter.boling@gmail.com>

* 👷 Lock rubygems and bundler for ancient matrix

Signed-off-by: Peter Boling <peter.boling@gmail.com>

* 👷 Improving designations of experimental jobs

Signed-off-by: Peter Boling <peter.boling@gmail.com>

* 👷 Fix Bundle for coverage and style workflows

Signed-off-by: Peter Boling <peter.boling@gmail.com>

* 👷 MultiXml parser set to :rexml

- remove wwtd gem dependency

Signed-off-by: Peter Boling <peter.boling@gmail.com>

* 🚨 Lint whitespace

Signed-off-by: Peter Boling <peter.boling@gmail.com>

* ➖ Kill rdoc

Signed-off-by: Peter Boling <peter.boling@gmail.com>

* 👷 Fix workflow name

Signed-off-by: Peter Boling <peter.boling@gmail.com>

* 👷 Avoid bundler bugs

Signed-off-by: Peter Boling <peter.boling@gmail.com>

* 👷 No truffleruby build on Windows

Signed-off-by: Peter Boling <peter.boling@gmail.com>

* 👷 Old MacOS

Signed-off-by: Peter Boling <peter.boling@gmail.com>

* 👷 Xenial Xerus doesn't seen to build

Signed-off-by: Peter Boling <peter.boling@gmail.com>

* ✅ Testing ancient Rubies may not be possible

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 .document                                     |   3 +-
 .github/workflows/coverage.yml                |  12 +-
 .github/workflows/danger.yml                  |  10 ++
 .github/workflows/heads.yml                   |  73 ++++++++++++
 .github/workflows/macos-ancient.yml           |  58 ++++++++++
 .github/workflows/macos.yml                   |  61 ++++++++++
 .github/workflows/style.yml                   |   7 ++
 .github/workflows/supported.yml               |  28 ++---
 .github/workflows/unsupported.yml             |  40 +++----
 .github/workflows/windows.yml                 |  60 ++++++++++
 .rubocop_todo.yml                             |  11 +-
 .simplecov                                    |   2 +
 Gemfile                                       |   1 -
 Rakefile                                      |  27 ++---
 gemfiles/README.md                            | 106 ++++++++++++++++++
 gemfiles/f0.gemfile                           |  11 ++
 gemfiles/f1.gemfile                           |   9 ++
 gemfiles/f2.gemfile                           |   9 ++
 gemfiles/jruby_1.7.gemfile                    |   2 +
 gemfiles/jruby_9.0.gemfile                    |   2 +
 gemfiles/jruby_9.1.gemfile                    |   2 +
 gemfiles/jruby_9.2.gemfile                    |   2 +
 gemfiles/jruby_head.gemfile                   |   2 +
 gemfiles/ruby_1.9.gemfile                     |   2 +
 gemfiles/ruby_2.0.gemfile                     |   2 +
 gemfiles/ruby_head.gemfile                    |   2 +
 gemfiles/truffleruby.gemfile                  |   2 +
 lib/oauth2.rb                                 |   2 +
 lib/oauth2/access_token.rb                    |   2 +
 lib/oauth2/authenticator.rb                   |   2 +
 lib/oauth2/client.rb                          |   2 +
 lib/oauth2/error.rb                           |   2 +
 lib/oauth2/mac_token.rb                       |   2 +
 lib/oauth2/response.rb                        |   2 +
 lib/oauth2/strategy/assertion.rb              |   2 +
 lib/oauth2/strategy/auth_code.rb              |   2 +
 lib/oauth2/strategy/base.rb                   |   2 +
 lib/oauth2/strategy/client_credentials.rb     |   2 +
 lib/oauth2/strategy/implicit.rb               |   2 +
 lib/oauth2/strategy/password.rb               |   2 +
 oauth2.gemspec                                |   6 +-
 spec/helper.rb                                |   2 +
 spec/oauth2/access_token_spec.rb              |   2 +
 spec/oauth2/authenticator_spec.rb             |   2 +
 spec/oauth2/client_spec.rb                    |   1 +
 spec/oauth2/mac_token_spec.rb                 |   2 +
 spec/oauth2/response_spec.rb                  |   6 +
 spec/oauth2/strategy/assertion_spec.rb        |   2 +
 spec/oauth2/strategy/auth_code_spec.rb        |   1 +
 spec/oauth2/strategy/base_spec.rb             |   2 +
 .../strategy/client_credentials_spec.rb       |   2 +
 spec/oauth2/strategy/implicit_spec.rb         |   2 +
 spec/oauth2/strategy/password_spec.rb         |   2 +
 53 files changed, 528 insertions(+), 76 deletions(-)
 create mode 100644 .github/workflows/heads.yml
 create mode 100644 .github/workflows/macos-ancient.yml
 create mode 100644 .github/workflows/macos.yml
 create mode 100644 .github/workflows/windows.yml
 create mode 100644 gemfiles/README.md
 create mode 100644 gemfiles/f0.gemfile
 create mode 100644 gemfiles/f1.gemfile
 create mode 100644 gemfiles/f2.gemfile

diff --git a/.document b/.document
index ecf36731..6f40d63c 100644
--- a/.document
+++ b/.document
@@ -1,5 +1,4 @@
-README.rdoc
+README.md
 lib/**/*.rb
 bin/*
-features/**/*.feature
 LICENSE
diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml
index 0ab4371a..c3c94a5c 100644
--- a/.github/workflows/coverage.yml
+++ b/.github/workflows/coverage.yml
@@ -28,26 +28,18 @@ concurrency:
 
 jobs:
   test:
-    name: Specs with Coverage - Ruby ${{ matrix.ruby }} ${{ matrix.name_extra || '' }}
+    name: Specs with Coverage - Ruby ${{ matrix.ruby }} ${{matrix.gemfile}} ${{ matrix.name_extra || '' }}
     if: "!contains(github.event.commits[0].message, '[ci skip]') && !contains(github.event.commits[0].message, '[skip ci]')"
     strategy:
       fail-fast: false
       matrix:
+        experimental: [false]
         rubygems:
           - latest
         bundler:
           - latest
         ruby:
           - "2.7"
-        include:
-          # Includes a new variable experimental with a value of false
-          #   for the matrix legs matching rubygems: latest, which is all of them.
-          # This is here for parity with the unsupported.yml
-          # This is a hack. Combined with continue-on-error it should allow us
-          #   to have a workflow with allowed failure.
-          # This is the "supported" build matrix, so only the "head" builds are experimental here.
-          - rubygems: latest
-            experimental: false
 
     runs-on: ubuntu-latest
     continue-on-error: ${{ matrix.experimental || endsWith(matrix.ruby, 'head') }}
diff --git a/.github/workflows/danger.yml b/.github/workflows/danger.yml
index 93812baf..7723f57c 100644
--- a/.github/workflows/danger.yml
+++ b/.github/workflows/danger.yml
@@ -10,11 +10,19 @@ on:
 jobs:
   danger:
     runs-on: ubuntu-latest
+    env: # $BUNDLE_GEMFILE must be set at the job level, so it is set for all steps
+      BUNDLE_GEMFILE: ${{ github.workspace }}/gemfiles/${{ matrix.gemfile }}.gemfile
     if: false
     # if: github.event_name  == 'pull_request' # if only run pull request when multiple trigger workflow
     strategy:
       fail-fast: false
       matrix:
+        gemfile:
+          - f2
+        rubygems:
+          - latest
+        bundler:
+          - latest
         ruby:
           - 2.7
     steps:
@@ -26,6 +34,8 @@ jobs:
         uses: ruby/setup-ruby@v1
         with:
           ruby-version: ${{ matrix.ruby }}
+          rubygems: ${{ matrix.rubygems }}
+          bundler: ${{ matrix.bundler }}
           bundler-cache: true
       - uses: MeilCli/danger-action@v5
         with:
diff --git a/.github/workflows/heads.yml b/.github/workflows/heads.yml
new file mode 100644
index 00000000..6dece37c
--- /dev/null
+++ b/.github/workflows/heads.yml
@@ -0,0 +1,73 @@
+name: Heads
+
+on:
+  push:
+    branches:
+      - 'main'
+      - 'master'
+      - '*-maintenance'
+      - '*-dev'
+      - '*-stable'
+    tags:
+      - '!*' # Do not execute on tags
+  pull_request:
+    branches:
+      - '*'
+  # Allow manually triggering the workflow.
+  workflow_dispatch:
+
+# Cancels all previous workflow runs for the same branch that have not yet completed.
+concurrency:
+  # The concurrency group contains the workflow name and the branch name.
+  group: ${{ github.workflow }}-${{ github.ref }}
+  cancel-in-progress: true
+
+jobs:
+  test:
+    name: Specs - Ruby ${{ matrix.ruby }} ${{matrix.gemfile}} ${{ matrix.name_extra || '' }}
+    env: # $BUNDLE_GEMFILE must be set at the job level, so it is set for all steps
+      BUNDLE_GEMFILE: ${{ github.workspace }}/gemfiles/${{ matrix.gemfile }}.gemfile
+    if: "!contains(github.event.commits[0].message, '[ci skip]') && !contains(github.event.commits[0].message, '[skip ci]')"
+    strategy:
+      fail-fast: false
+      matrix:
+        experimental: [true]
+        gemfile:
+          - f0
+          - f1
+          - f2
+        rubygems:
+          - latest
+        bundler:
+          - latest
+        ruby:
+          - truffleruby+graalvm-head
+          - truffleruby-head
+          - jruby-head
+          - ruby-head
+        include:
+          # Includes a new variable experimental with a value of false
+          #   for the matrix legs matching rubygems: latest, which is all of them.
+          # This is here for parity with the unsupported.yml
+          # This is a hack. Combined with continue-on-error it should allow us
+          #   to have a workflow with allowed failure.
+          # This is the "supported" build matrix, so only the "head" builds are experimental here.
+          - rubygems: latest
+            experimental: true
+
+    runs-on: ubuntu-latest
+    continue-on-error: ${{ matrix.experimental || endsWith(matrix.ruby, 'head') }}
+    steps:
+      - name: Checkout
+        uses: actions/checkout@v2
+      - name: Install cURL Headers
+        run: sudo apt-get install libcurl4-openssl-dev
+      - name: Setup Ruby & Bundle
+        uses: ruby/setup-ruby@v1
+        with:
+          ruby-version: ${{ matrix.ruby }}
+          rubygems: ${{ matrix.rubygems }}
+          bundler: ${{ matrix.bundler }}
+          bundler-cache: true
+      - name: Run tests
+        run: bundle exec rake test
diff --git a/.github/workflows/macos-ancient.yml b/.github/workflows/macos-ancient.yml
new file mode 100644
index 00000000..ba2ebf62
--- /dev/null
+++ b/.github/workflows/macos-ancient.yml
@@ -0,0 +1,58 @@
+name: Old MacOS
+
+on:
+  push:
+    branches:
+      - 'main'
+      - 'master'
+      - '*-maintenance'
+      - '*-dev'
+      - '*-stable'
+    tags:
+      - '!*' # Do not execute on tags
+  pull_request:
+    branches:
+      - '*'
+  # Allow manually triggering the workflow.
+  workflow_dispatch:
+
+# Cancels all previous workflow runs for the same branch that have not yet completed.
+concurrency:
+  # The concurrency group contains the workflow name and the branch name.
+  group: ${{ github.workflow }}-${{ github.ref }}
+  cancel-in-progress: true
+
+jobs:
+  test:
+    name: Specs - Ruby ${{ matrix.ruby }} ${{matrix.gemfile}} ${{ matrix.name_extra || '' }}
+    env: # $BUNDLE_GEMFILE must be set at the job level, so it is set for all steps
+      BUNDLE_GEMFILE: ${{ github.workspace }}/gemfiles/${{ matrix.gemfile }}.gemfile
+    if: false
+    # if: "!contains(github.event.commits[0].message, '[ci skip]') && !contains(github.event.commits[0].message, '[skip ci]')"
+    strategy:
+      fail-fast: false
+      matrix:
+        experimental: [true]
+        gemfile:
+          - f0
+        rubygems:
+          - "2.7.11"
+        ruby:
+          - "1.9"
+          - "2.0"
+          - "2.1"
+          - "2.2"
+
+    runs-on: macos-10.15
+    continue-on-error: ${{ matrix.experimental || endsWith(matrix.ruby, 'head') }}
+    steps:
+      - name: Checkout
+        uses: actions/checkout@v2
+      - name: Setup Ruby & Bundle
+        uses: ruby/setup-ruby@v1
+        with:
+          ruby-version: ${{ matrix.ruby }}
+          rubygems: ${{ matrix.rubygems }}
+          bundler-cache: true
+      - name: Run tests
+        run: bundle exec rake test
diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml
new file mode 100644
index 00000000..24a0e8a7
--- /dev/null
+++ b/.github/workflows/macos.yml
@@ -0,0 +1,61 @@
+name: MacOS
+
+on:
+  push:
+    branches:
+      - 'main'
+      - 'master'
+      - '*-maintenance'
+      - '*-dev'
+      - '*-stable'
+    tags:
+      - '!*' # Do not execute on tags
+  pull_request:
+    branches:
+      - '*'
+  # Allow manually triggering the workflow.
+  workflow_dispatch:
+
+# Cancels all previous workflow runs for the same branch that have not yet completed.
+concurrency:
+  # The concurrency group contains the workflow name and the branch name.
+  group: ${{ github.workflow }}-${{ github.ref }}
+  cancel-in-progress: true
+
+jobs:
+  test:
+    name: Specs - Ruby ${{ matrix.ruby }} ${{matrix.gemfile}} ${{ matrix.name_extra || '' }}
+    env: # $BUNDLE_GEMFILE must be set at the job level, so it is set for all steps
+      BUNDLE_GEMFILE: ${{ github.workspace }}/gemfiles/${{ matrix.gemfile }}.gemfile
+    if: "!contains(github.event.commits[0].message, '[ci skip]') && !contains(github.event.commits[0].message, '[skip ci]')"
+    strategy:
+      fail-fast: false
+      matrix:
+        experimental: [true]
+        gemfile:
+          - f2
+        rubygems:
+          - latest
+        bundler:
+          - latest
+        ruby:
+          - "2.7"
+          - "3.0"
+          - "3.1"
+          - truffleruby
+          - jruby
+
+    runs-on: macos-latest
+    continue-on-error: ${{ matrix.experimental || endsWith(matrix.ruby, 'head') }}
+    steps:
+      - name: Checkout
+        uses: actions/checkout@v2
+      - name: Setup Ruby & Bundle
+        uses: ruby/setup-ruby@v1
+        with:
+          ruby-version: ${{ matrix.ruby }}
+          rubygems: ${{ matrix.rubygems }}
+          bundler: ${{ matrix.bundler }}
+          bundler-cache: true
+      - name: Run tests
+        run: bundle exec rake test
diff --git a/.github/workflows/style.yml b/.github/workflows/style.yml
index 539b3576..22c5ac70 100644
--- a/.github/workflows/style.yml
+++ b/.github/workflows/style.yml
@@ -21,6 +21,11 @@ jobs:
     strategy:
       fail-fast: false
       matrix:
+        experimental: [false]
+        rubygems:
+          - latest
+        bundler:
+          - latest
         ruby:
           - 2.7
     runs-on: ubuntu-latest
@@ -33,6 +38,8 @@ jobs:
         uses: ruby/setup-ruby@v1
         with:
           ruby-version: ${{ matrix.ruby }}
+          rubygems: ${{ matrix.rubygems }}
+          bundler: ${{ matrix.bundler }}
           bundler-cache: true
       - name: Run Rubocop
         run: bundle exec rubocop -DESP
diff --git a/.github/workflows/supported.yml b/.github/workflows/supported.yml
index 62312ed4..b0e3b5a6 100644
--- a/.github/workflows/supported.yml
+++ b/.github/workflows/supported.yml
@@ -1,4 +1,4 @@
-name: Supported Ruby Unit Tests
+name: Official Support
 
 on:
   push:
@@ -24,32 +24,28 @@ concurrency:
 
 jobs:
   test:
-    name: Specs - Ruby ${{ matrix.ruby }} ${{ matrix.name_extra || '' }}
+    name: Specs - Ruby ${{ matrix.ruby }} ${{matrix.gemfile}} ${{ matrix.name_extra || '' }}
+    env: # $BUNDLE_GEMFILE must be set at the job level, so it is set for all steps
+      BUNDLE_GEMFILE: ${{ github.workspace }}/gemfiles/${{ matrix.gemfile }}.gemfile
     if: "!contains(github.event.commits[0].message, '[ci skip]') && !contains(github.event.commits[0].message, '[skip ci]')"
     strategy:
       fail-fast: false
       matrix:
+        experimental: [false]
+        gemfile:
+          - f0
+          - f1
+          - f2
         rubygems:
           - latest
         bundler:
           - latest
         ruby:
-          - truffleruby-head
+          - "2.7"
+          - "3.0"
+          - "3.1"
           - truffleruby
-          - jruby-head
           - jruby
-          - "3.1"
-          - "3.0"
-          # - "2.7" tested in coverage workflow
-        include:
-          # Includes a new variable experimental with a value of false
-          #   for the matrix legs matching rubygems: latest, which is all of them.
-          # This is here for parity with the unsupported.yml
-          # This is a hack. Combined with continue-on-error it should allow us
-          #   to have a workflow with allowed failure.
-          # This is the "supported" build matrix, so only the "head" builds are experimental here.
-          - rubygems: latest
-            experimental: false
 
     runs-on: ubuntu-latest
     continue-on-error: ${{ matrix.experimental || endsWith(matrix.ruby, 'head') }}
diff --git a/.github/workflows/unsupported.yml b/.github/workflows/unsupported.yml
index 8206a092..3b4ee3fb 100644
--- a/.github/workflows/unsupported.yml
+++ b/.github/workflows/unsupported.yml
@@ -1,4 +1,4 @@
-name: Unsupported Ruby Unit Tests
+name: Unofficial Support
 
 on:
   push:
@@ -24,34 +24,36 @@ concurrency:
 
 jobs:
   test:
-    name: Specs - Ruby ${{ matrix.ruby }} ${{ matrix.name_extra || '' }}
+    name: Specs - Ruby ${{ matrix.ruby }} ${{matrix.gemfile}} ${{ matrix.name_extra || '' }}
+    env: # $BUNDLE_GEMFILE must be set at the job level, so it is set for all steps
+      BUNDLE_GEMFILE: ${{ github.workspace }}/gemfiles/${{ matrix.gemfile }}.gemfile
     if: "!contains(github.event.commits[0].message, '[ci skip]') && !contains(github.event.commits[0].message, '[skip ci]')"
     strategy:
       fail-fast: false
       matrix:
+        experimental: [false]
+        gemfile:
+          - f0
+          - f1
+          - f2
         rubygems:
           - latest
         bundler:
           - latest
         ruby:
-          - ruby-head
-          - "2.6"
-          - "2.5"
-          - "2.4"
           - "2.3"
-          - "2.2"
-          - "2.1"
-        include:
-          # Includes a new variable experimental with a value of true
-          #   for the matrix legs matching rubygems: latest, which is all of them.
-          # This is the "unsupported" build matrix, so only many builds are experimental here.
-          # Even so, we do want to "support" some of the EOL rubies in the 1.4.x series on a marginal basis.
-          - ruby: ruby-head
-            experimental: true
-          - ruby: "2.1"
-            experimental: true
-          - ruby: "2.2"
-            experimental: true
+          - "2.4"
+          - "2.5"
+          - "2.6"
+        exclude:
+          - ruby: "2.3"
+            gemfile: "f1"
+          - ruby: "2.3"
+            gemfile: "f2"
+          - ruby: "2.4"
+            gemfile: "f2"
+          - ruby: "2.5"
+            gemfile: "f2"
 
     runs-on: ubuntu-20.04
     continue-on-error: ${{ matrix.experimental || endsWith(matrix.ruby, 'head') }}
diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml
new file mode 100644
index 00000000..4f97a0da
--- /dev/null
+++ b/.github/workflows/windows.yml
@@ -0,0 +1,60 @@
+name: Windows
+
+on:
+  push:
+    branches:
+      - 'main'
+      - 'master'
+      - '*-maintenance'
+      - '*-dev'
+      - '*-stable'
+    tags:
+      - '!*' # Do not execute on tags
+  pull_request:
+    branches:
+      - '*'
+  # Allow manually triggering the workflow.
+  workflow_dispatch:
+
+# Cancels all previous workflow runs for the same branch that have not yet completed.
+concurrency:
+  # The concurrency group contains the workflow name and the branch name.
+  group: ${{ github.workflow }}-${{ github.ref }}
+  cancel-in-progress: true
+
+jobs:
+  test:
+    name: Specs - Ruby ${{ matrix.ruby }} ${{matrix.gemfile}} ${{ matrix.name_extra || '' }}
+    env: # $BUNDLE_GEMFILE must be set at the job level, so it is set for all steps
+      BUNDLE_GEMFILE: ${{ github.workspace }}/gemfiles/${{ matrix.gemfile }}.gemfile
+    if: "!contains(github.event.commits[0].message, '[ci skip]') && !contains(github.event.commits[0].message, '[skip ci]')"
+    strategy:
+      fail-fast: false
+      matrix:
+        experimental: [true]
+        gemfile:
+          - f2
+        rubygems:
+          - latest
+        bundler:
+          - latest
+        ruby:
+          - "2.7"
+          - "3.0"
+          - "3.1"
+          - jruby
+
+    runs-on: windows-latest
+    continue-on-error: ${{ matrix.experimental || endsWith(matrix.ruby, 'head') }}
+    steps:
+      - name: Checkout
+        uses: actions/checkout@v2
+      - name: Setup Ruby & Bundle
+        uses: ruby/setup-ruby@v1
+        with:
+          ruby-version: ${{ matrix.ruby }}
+          rubygems: ${{ matrix.rubygems }}
+          bundler: ${{ matrix.bundler }}
+          bundler-cache: true
+      - name: Run tests
+        run: bundle exec rake test
diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml
index 0be291e3..bae0df7a 100644
--- a/.rubocop_todo.yml
+++ b/.rubocop_todo.yml
@@ -1,6 +1,6 @@
 # This configuration was generated by
 # `rubocop --auto-gen-config`
-# on 2022-02-18 23:52:28 UTC using RuboCop version 1.25.1.
+# on 2022-02-20 04:57:56 UTC using RuboCop version 1.25.1.
 # The point is for the user to remove these configuration records
 # one by one as the offenses are removed from the code base.
 # Note that changes in the inspected code, or installation of new
@@ -46,7 +46,7 @@ Metrics/MethodLength:
 Metrics/PerceivedComplexity:
   Max: 11
 
-# Offense count: 3
+# Offense count: 1
 # Configuration parameters: EnforcedStyle, CheckMethodNames, CheckSymbols, AllowedIdentifiers.
 # SupportedStyles: snake_case, normalcase, non_integer
 # AllowedIdentifiers: capture3, iso8601, rfc1123_date, rfc822, rfc2822, rfc3339
@@ -81,13 +81,6 @@ Rake/Desc:
   Exclude:
     - 'Rakefile'
 
-# Offense count: 37
-# Cop supports --auto-correct.
-# Configuration parameters: EnforcedStyle.
-# SupportedStyles: always, always_true, never
-Style/FrozenStringLiteralComment:
-  Enabled: false
-
 # Offense count: 3
 # Cop supports --auto-correct-all.
 # Configuration parameters: Mode.
diff --git a/.simplecov b/.simplecov
index a36a7c57..77f4b3f3 100644
--- a/.simplecov
+++ b/.simplecov
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 # To get coverage
 # On Local, default (HTML) output, it just works, coverage is turned on:
 #   bundle exec rspec spec
diff --git a/Gemfile b/Gemfile
index 1dbda68d..e4884b03 100644
--- a/Gemfile
+++ b/Gemfile
@@ -6,7 +6,6 @@ gemspec
 
 git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
 
-gem 'faraday', ['>= 0.8', '< 3.0'], :platforms => [:jruby_18, :ruby_18]
 gem 'jwt'
 gem 'overcommit'
 gem 'rake'
diff --git a/Rakefile b/Rakefile
index 19bdfa31..f8c96f3a 100644
--- a/Rakefile
+++ b/Rakefile
@@ -1,15 +1,10 @@
 # encoding: utf-8
+# frozen_string_literal: true
 
 # !/usr/bin/env rake
 
 require 'bundler/gem_tasks'
 
-begin
-  require 'wwtd/tasks'
-rescue LoadError
-  puts 'failed to load wwtd'
-end
-
 begin
   require 'rspec/core/rake_task'
   RSpec::Core::RakeTask.new(:spec)
@@ -31,15 +26,15 @@ rescue LoadError
   end
 end
 
-namespace :doc do
-  require 'rdoc/task'
-  require 'oauth2/version'
-  RDoc::Task.new do |rdoc|
-    rdoc.rdoc_dir = 'rdoc'
-    rdoc.title = "oauth2 #{OAuth2::Version}"
-    rdoc.main = 'README.md'
-    rdoc.rdoc_files.include('README.md', 'LICENSE.md', 'lib/**/*.rb')
-  end
-end
+# namespace :doc do
+#   require 'rdoc/task'
+#   require 'oauth2/version'
+#   RDoc::Task.new do |rdoc|
+#     rdoc.rdoc_dir = 'rdoc'
+#     rdoc.title = "oauth2 #{OAuth2::Version}"
+#     rdoc.main = 'README.md'
+#     rdoc.rdoc_files.include('README.md', 'LICENSE.md', 'lib/**/*.rb')
+#   end
+# end
 
 task :default => [:test, :rubocop]
diff --git a/gemfiles/README.md b/gemfiles/README.md
new file mode 100644
index 00000000..1ac3a713
--- /dev/null
+++ b/gemfiles/README.md
@@ -0,0 +1,106 @@
+# History
+
+`faraday` v0.17.3 is the first version that stops using `&Proc.new` for block forwarding,
+   and thus is the oldest version oauth2 is compatible with.
+
+```ruby
+gem 'faraday', ['>= 0.17.3', '< 3.0']
+```
+
+# Ruby
+
+We use the Github Action `ruby/setup-ruby@master` to install Ruby, and it has a matrix of
+[supported versions](https://github.com/ruby/setup-ruby/blob/master/README.md#supported-versions) (copied below).
+
+| Interpreter           | Versions                                                                                 |
+|-----------------------|------------------------------------------------------------------------------------------|
+| `ruby`                | 1.9.3, 2.0.0, 2.1.9, 2.2, all versions from 2.3.0 until 3.1.1, head, debug, mingw, mswin |
+| `jruby`               | 9.1.17.0 - 9.3.3.0, head                                                                 |
+| `truffleruby`         | 19.3.0 - 22.0.0, head                                                                    |
+| `truffleruby+graalvm` | 21.2.0 - 22.0.0, head                                                                    |
+
+In the naming of gemfiles, we will use the below shorthand for interpreter,
+and version. Platforms will be represented without modification.
+
+| Interpreter           | Shorthand |
+|-----------------------|-----------|
+| `ruby`                | r         |
+| `jruby`               | jr        |
+| `truffleruby`         | tr        |
+| `truffleruby+graalvm` | trg       |
+
+Building onto that, we can add the MRI target spec,
+since that's what all Rubygems use for minimum version compatibility.
+
+| Interpreter + Version      | MRI spec | Shorthand  |
+|----------------------------|----------|------------|
+| ruby-1.9.3                 | 1.9      | r1_9       |
+| ruby-2.0.0                 | 2.0      | r2_0       |
+| ruby-2.1.9                 | 2.1      | r2_1       |
+| ruby-2.2.x                 | 2.2      | r2_2       |
+| ruby-2.3.x                 | 2.3      | r2_3       |
+| ruby-2.4.x                 | 2.4      | r2_4       |
+| ruby-2.5.x                 | 2.5      | r2_5       |
+| ruby-2.6.x                 | 2.6      | r2_6       |
+| ruby-2.7.x                 | 2.7      | r2_7       |
+| ruby-3.0.x                 | 3.0      | r3_0       |
+| ruby-3.1.x                 | 3.1      | r3_1       |
+| ruby-head                  | 3.2      | rH3_2      |
+| ruby-mingw                 | (?)      | rmin       |
+| ruby-mswin                 | (?)      | rMS        |
+| jruby-9.1.x.x              | 2.3      | jr9_1-r2_3 |
+| jruby-9.2.x.x              | 2.5      | jr9_2-r2_5 |
+| jruby-9.3.x.x              | 2.6      | jr9_3-r2_6 |
+| jruby-head                 | 2.7      | jrH-r2_7   |
+| truffleruby-19.3.x         | 2.5(?)   | tr19-r2_5  |
+| truffleruby-20.x.x         | 2.6.5    | tr20-r2_6  |
+| truffleruby-21.x.x         | 2.7.4    | tr21-r2_7  |
+| truffleruby-22.x.x         | 3.0.2    | tr22-r3_0  |
+| truffleruby-head           | 3.1(?)   | trH-r3_1   |
+| truffleruby+graalvm-21.2.x | 2.7.4    | trg21-r2_7 |
+| truffleruby+graalvm-22.x.x | 3.0.2    | trg22-r3_0 |
+| truffleruby+graalvm-head   | 3.1(?)   | trgH-r3_1  |
+
+We will run tests on as many of these as possible, in a matrix with each supported major version of `faraday`,
+which means 0.17.3+ (as `f0`), 1.10.x (as `f1`), 2.2.x (as `f2`).
+
+Discrete versions of `faraday` to test against, as of 2022.02.19, with minimum version of Ruby for each:
+
+* 2.2.0, Ruby >= 2.6
+* 1.10.0, Ruby >= 2.4
+* 0.17.4, Ruby >= 1.9
+
+❌ - Incompatible
+✅ - Official Support
+🚧 - Unofficial Support
+🤡 - Incidental Compatibility
+🙈 - Unknown Compatibility
+
+| Shorthand  | f0 - 0.17.3+     | f1 - 1.10.x      | f2 - 2.2.x      |
+|------------|------------------|------------------|-----------------|
+| r1_9       | 🤡 f0-r1_9       | ❌                | ❌               |
+| r2_0       | 🤡 f0-r2_0       | ❌                | ❌               |
+| r2_1       | 🤡 f0-r2_1       | ❌                | ❌               |
+| r2_2       | 🤡 f0-r2_2       | ❌                | ❌               |
+| r2_3       | 🚧 f0-r2_3       | ❌                | ❌               |
+| r2_4       | 🚧 f0-r2_4       | 🚧 f1-r2_4       | ❌               |
+| r2_5       | 🚧 f0-r2_5       | 🚧 f1-r2_5       | ❌               |
+| r2_6       | 🚧 f0-r2_6       | 🚧 f1-r2_6       | 🚧 f2-r2_6      |
+| r2_7       | ✅ f0-r2_7        | ✅ f1-r2_7        | ✅ f2-r2_7       |
+| r3_0       | ✅ f0-r3_0        | ✅ f1-r3_0        | ✅ f2-r3_0       |
+| r3_1       | ✅ f0-r3_1        | ✅ f1-r3_1        | ✅ f2-r3_1       |
+| rH3_2      | 🚧 f0-rH3_2      | 🚧 f1-rH3_2      | 🚧 f2-rH3_2     |
+| rmin       | 🙈 f0-rmin       | 🙈 f1-rmin       | 🙈 f2-rmin      |
+| rMS        | 🙈 f0-rMS        | 🙈 f1-rMS        | 🙈 f2-rMS       |
+| jr9_1-r2_3 | 🚧 f0-jr9_1-r2_3 | ❌                | ❌               |
+| jr9_2-r2_5 | 🚧 f0-jr9_2-r2_5 | 🚧 f1-jr9_2-r2_5 | ❌               |
+| jr9_3-r2_6 | ✅ f0-jr9_3-r2_6  | ✅ f1-jr9_3-r2_6  | ✅ f2-jr9_3-r2_6 |
+| jrH-r2_7   | 🚧 f0-jrH-r2_7    | 🚧 f1-jrH-r2_7    | 🚧 f2-jrH-r2_7   |
+| tr19-r2_5  | 🚧 f0-tr19-r2_5  | 🚧 f1-tr19-r2_5  | ❌               |
+| tr20-r2_6  | 🚧 f0-tr20-r2_6  | 🚧 f1-tr20-r2_6  | 🚧 f2-tr20-r2_6 |
+| tr21-r2_7  | ✅ f0-tr21-r2_7   | ✅ f1-tr21-r2_7   | ✅ f2-tr21-r2_7  |
+| tr22-r3_0  | ✅ f0-tr22-r3_0   | ✅ f1-tr22-r3_0   | ✅ f2-tr22-r3_0  |
+| trH-r3_1   | 🚧 f0-trH-r3_1   | 🚧 f1-trH-r3_1   | 🚧 f2-trH-r3_1  |
+| trg21-r2_7 | ✅ f0-trg21-r2_7  | ✅ f1-trg21-r2_7  | ✅ f2-trg21-r2_7 |
+| trg22-r3_0 | ✅ f0-trg22-r3_0  | ✅ f1-trg22-r3_0  | ✅ f2-trg22-r3_0 |
+| trgH-r3_1  | 🚧 f0-trgH-r3_1  | 🚧 f1-trgH-r3_1  | 🚧 f2-trgH-r3_1 |
diff --git a/gemfiles/f0.gemfile b/gemfiles/f0.gemfile
new file mode 100644
index 00000000..67b7e01f
--- /dev/null
+++ b/gemfiles/f0.gemfile
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+source 'https://rubygems.org'
+
+# See README.md in this directory
+
+# 0.17.3 is the first version that stops using &Proc.new for block forwarding,
+#   and thus is the oldest version oauth2 is compatible with.
+gem 'faraday', '~> 0.17.4'
+
+gemspec :path => '../'
diff --git a/gemfiles/f1.gemfile b/gemfiles/f1.gemfile
new file mode 100644
index 00000000..f048505b
--- /dev/null
+++ b/gemfiles/f1.gemfile
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+source 'https://rubygems.org'
+
+# See README.md in this directory
+
+gem 'faraday', '~> 1.10'
+
+gemspec :path => '../'
diff --git a/gemfiles/f2.gemfile b/gemfiles/f2.gemfile
new file mode 100644
index 00000000..4724ca55
--- /dev/null
+++ b/gemfiles/f2.gemfile
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+source 'https://rubygems.org'
+
+# See README.md in this directory
+
+gem 'faraday', '~> 2.2'
+
+gemspec :path => '../'
diff --git a/gemfiles/jruby_1.7.gemfile b/gemfiles/jruby_1.7.gemfile
index 276621ef..5d23c8b9 100644
--- a/gemfiles/jruby_1.7.gemfile
+++ b/gemfiles/jruby_1.7.gemfile
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 source 'https://rubygems.org'
 
 gem 'faraday', '~> 0.15.4'
diff --git a/gemfiles/jruby_9.0.gemfile b/gemfiles/jruby_9.0.gemfile
index 6d3ebd53..1a2afca9 100644
--- a/gemfiles/jruby_9.0.gemfile
+++ b/gemfiles/jruby_9.0.gemfile
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 source 'https://rubygems.org'
 
 gem 'faraday', '~> 0.15.4'
diff --git a/gemfiles/jruby_9.1.gemfile b/gemfiles/jruby_9.1.gemfile
index a02c547f..c7770283 100644
--- a/gemfiles/jruby_9.1.gemfile
+++ b/gemfiles/jruby_9.1.gemfile
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 source 'https://rubygems.org'
 
 gemspec :path => '../'
diff --git a/gemfiles/jruby_9.2.gemfile b/gemfiles/jruby_9.2.gemfile
index a02c547f..c7770283 100644
--- a/gemfiles/jruby_9.2.gemfile
+++ b/gemfiles/jruby_9.2.gemfile
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 source 'https://rubygems.org'
 
 gemspec :path => '../'
diff --git a/gemfiles/jruby_head.gemfile b/gemfiles/jruby_head.gemfile
index a02c547f..c7770283 100644
--- a/gemfiles/jruby_head.gemfile
+++ b/gemfiles/jruby_head.gemfile
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 source 'https://rubygems.org'
 
 gemspec :path => '../'
diff --git a/gemfiles/ruby_1.9.gemfile b/gemfiles/ruby_1.9.gemfile
index 276621ef..5d23c8b9 100644
--- a/gemfiles/ruby_1.9.gemfile
+++ b/gemfiles/ruby_1.9.gemfile
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 source 'https://rubygems.org'
 
 gem 'faraday', '~> 0.15.4'
diff --git a/gemfiles/ruby_2.0.gemfile b/gemfiles/ruby_2.0.gemfile
index 87a679f6..cc675c47 100644
--- a/gemfiles/ruby_2.0.gemfile
+++ b/gemfiles/ruby_2.0.gemfile
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 source 'https://rubygems.org'
 
 gem 'faraday', '~> 0.15.4'
diff --git a/gemfiles/ruby_head.gemfile b/gemfiles/ruby_head.gemfile
index c7a3bfd9..03b6a53c 100644
--- a/gemfiles/ruby_head.gemfile
+++ b/gemfiles/ruby_head.gemfile
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 source 'https://rubygems.org'
 
 group :development do
diff --git a/gemfiles/truffleruby.gemfile b/gemfiles/truffleruby.gemfile
index a02c547f..c7770283 100644
--- a/gemfiles/truffleruby.gemfile
+++ b/gemfiles/truffleruby.gemfile
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 source 'https://rubygems.org'
 
 gemspec :path => '../'
diff --git a/lib/oauth2.rb b/lib/oauth2.rb
index 5a7ed9fe..77a93f56 100644
--- a/lib/oauth2.rb
+++ b/lib/oauth2.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 require 'oauth2/error'
 require 'oauth2/authenticator'
 require 'oauth2/client'
diff --git a/lib/oauth2/access_token.rb b/lib/oauth2/access_token.rb
index 90bff28d..c6568049 100644
--- a/lib/oauth2/access_token.rb
+++ b/lib/oauth2/access_token.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module OAuth2
   class AccessToken
     attr_reader :client, :token, :expires_in, :expires_at, :params
diff --git a/lib/oauth2/authenticator.rb b/lib/oauth2/authenticator.rb
index 48158072..34b696a3 100644
--- a/lib/oauth2/authenticator.rb
+++ b/lib/oauth2/authenticator.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 require 'base64'
 
 module OAuth2
diff --git a/lib/oauth2/client.rb b/lib/oauth2/client.rb
index 88aa5d4e..611dab24 100644
--- a/lib/oauth2/client.rb
+++ b/lib/oauth2/client.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 require 'faraday'
 require 'logger'
 
diff --git a/lib/oauth2/error.rb b/lib/oauth2/error.rb
index 58e91dc9..64f63292 100644
--- a/lib/oauth2/error.rb
+++ b/lib/oauth2/error.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module OAuth2
   class Error < StandardError
     attr_reader :response, :code, :description
diff --git a/lib/oauth2/mac_token.rb b/lib/oauth2/mac_token.rb
index 36e95a2f..69c5ade2 100644
--- a/lib/oauth2/mac_token.rb
+++ b/lib/oauth2/mac_token.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 require 'base64'
 require 'digest'
 require 'openssl'
diff --git a/lib/oauth2/response.rb b/lib/oauth2/response.rb
index fd98617b..9a4f5d5c 100644
--- a/lib/oauth2/response.rb
+++ b/lib/oauth2/response.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 require 'multi_json'
 require 'multi_xml'
 require 'rack'
diff --git a/lib/oauth2/strategy/assertion.rb b/lib/oauth2/strategy/assertion.rb
index 1ea8415c..2f3351aa 100644
--- a/lib/oauth2/strategy/assertion.rb
+++ b/lib/oauth2/strategy/assertion.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 require 'jwt'
 
 module OAuth2
diff --git a/lib/oauth2/strategy/auth_code.rb b/lib/oauth2/strategy/auth_code.rb
index dff92922..b019ad95 100644
--- a/lib/oauth2/strategy/auth_code.rb
+++ b/lib/oauth2/strategy/auth_code.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module OAuth2
   module Strategy
     # The Authorization Code Strategy
diff --git a/lib/oauth2/strategy/base.rb b/lib/oauth2/strategy/base.rb
index 9d16bb4a..801a723e 100644
--- a/lib/oauth2/strategy/base.rb
+++ b/lib/oauth2/strategy/base.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module OAuth2
   module Strategy
     class Base
diff --git a/lib/oauth2/strategy/client_credentials.rb b/lib/oauth2/strategy/client_credentials.rb
index cfcecd56..778c4fa4 100644
--- a/lib/oauth2/strategy/client_credentials.rb
+++ b/lib/oauth2/strategy/client_credentials.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module OAuth2
   module Strategy
     # The Client Credentials Strategy
diff --git a/lib/oauth2/strategy/implicit.rb b/lib/oauth2/strategy/implicit.rb
index 15e99c07..00d3e4e9 100644
--- a/lib/oauth2/strategy/implicit.rb
+++ b/lib/oauth2/strategy/implicit.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module OAuth2
   module Strategy
     # The Implicit Strategy
diff --git a/lib/oauth2/strategy/password.rb b/lib/oauth2/strategy/password.rb
index a6498cd3..d41ca07a 100644
--- a/lib/oauth2/strategy/password.rb
+++ b/lib/oauth2/strategy/password.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 module OAuth2
   module Strategy
     # The Resource Owner Password Credentials Authorization Strategy
diff --git a/oauth2.gemspec b/oauth2.gemspec
index 8480ac0e..4c35df62 100644
--- a/oauth2.gemspec
+++ b/oauth2.gemspec
@@ -1,11 +1,12 @@
 # coding: utf-8
+# frozen_string_literal: true
 
 lib = File.expand_path('../lib', __FILE__)
 $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
 require 'oauth2/version'
 
 Gem::Specification.new do |spec|
-  spec.add_dependency 'faraday', ['>= 0.8', '< 3.0']
+  spec.add_dependency 'faraday', ['>= 0.17.3', '< 3.0']
   spec.add_dependency 'jwt', ['>= 1.0', '< 3.0']
   spec.add_dependency 'multi_json', '~> 1.3'
   spec.add_dependency 'multi_xml', '~> 0.5'
@@ -41,11 +42,10 @@ Gem::Specification.new do |spec|
   spec.add_development_dependency 'backports', '~> 3.11'
   spec.add_development_dependency 'bundler', '>= 1.16'
   spec.add_development_dependency 'rake', '~> 12.3'
-  spec.add_development_dependency 'rdoc', ['>= 5.0', '< 7']
+  spec.add_development_dependency 'rexml', '~> 3.2'
   spec.add_development_dependency 'rspec', '~> 3.0'
   spec.add_development_dependency 'rspec-block_is_expected'
   spec.add_development_dependency 'rspec-pending_for'
   spec.add_development_dependency 'rspec-stubbed_env'
   spec.add_development_dependency 'silent_stream'
-  spec.add_development_dependency 'wwtd'
 end
diff --git a/spec/helper.rb b/spec/helper.rb
index 414e229d..03d97bcc 100644
--- a/spec/helper.rb
+++ b/spec/helper.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 DEBUG = ENV['DEBUG'] == 'true'
 RUN_COVERAGE = ENV['CI_CODECOV'] || ENV['CI'].nil?
 
diff --git a/spec/oauth2/access_token_spec.rb b/spec/oauth2/access_token_spec.rb
index 8bf4c5ea..a205f443 100644
--- a/spec/oauth2/access_token_spec.rb
+++ b/spec/oauth2/access_token_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 describe OAuth2::AccessToken do
   subject { described_class.new(client, token) }
 
diff --git a/spec/oauth2/authenticator_spec.rb b/spec/oauth2/authenticator_spec.rb
index 48cbac9b..4448b98a 100644
--- a/spec/oauth2/authenticator_spec.rb
+++ b/spec/oauth2/authenticator_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 describe OAuth2::Authenticator do
   subject do
     described_class.new(client_id, client_secret, mode)
diff --git a/spec/oauth2/client_spec.rb b/spec/oauth2/client_spec.rb
index 67b70c7d..d5884264 100644
--- a/spec/oauth2/client_spec.rb
+++ b/spec/oauth2/client_spec.rb
@@ -1,4 +1,5 @@
 # coding: utf-8
+# frozen_string_literal: true
 
 require 'nkf'
 
diff --git a/spec/oauth2/mac_token_spec.rb b/spec/oauth2/mac_token_spec.rb
index b358a95a..eab2599b 100644
--- a/spec/oauth2/mac_token_spec.rb
+++ b/spec/oauth2/mac_token_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 describe OAuth2::MACToken do
   subject { described_class.new(client, token, 'abc123') }
 
diff --git a/spec/oauth2/response_spec.rb b/spec/oauth2/response_spec.rb
index 3171fd26..8e703aa1 100644
--- a/spec/oauth2/response_spec.rb
+++ b/spec/oauth2/response_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 describe OAuth2::Response do
   describe '#initialize' do
     let(:status) { 200 }
@@ -75,6 +77,10 @@
   end
 
   context 'with xml parser registration' do
+    before do
+      MultiXml.parser = :rexml
+    end
+
     it 'tries to load multi_xml and use it' do
       expect(described_class.send(:class_variable_get, :@@parsers)[:xml]).not_to be_nil
     end
diff --git a/spec/oauth2/strategy/assertion_spec.rb b/spec/oauth2/strategy/assertion_spec.rb
index bd05b2c6..cd54ba05 100644
--- a/spec/oauth2/strategy/assertion_spec.rb
+++ b/spec/oauth2/strategy/assertion_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 require 'openssl'
 
 describe OAuth2::Strategy::Assertion do
diff --git a/spec/oauth2/strategy/auth_code_spec.rb b/spec/oauth2/strategy/auth_code_spec.rb
index 36cd3a5a..465521f8 100644
--- a/spec/oauth2/strategy/auth_code_spec.rb
+++ b/spec/oauth2/strategy/auth_code_spec.rb
@@ -1,4 +1,5 @@
 # encoding: utf-8
+# frozen_string_literal: true
 
 describe OAuth2::Strategy::AuthCode do
   subject { client.auth_code }
diff --git a/spec/oauth2/strategy/base_spec.rb b/spec/oauth2/strategy/base_spec.rb
index 67c66d1a..87dd3266 100644
--- a/spec/oauth2/strategy/base_spec.rb
+++ b/spec/oauth2/strategy/base_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 describe OAuth2::Strategy::Base do
   it 'initializes with a Client' do
     expect { described_class.new(OAuth2::Client.new('abc', 'def')) }.not_to raise_error
diff --git a/spec/oauth2/strategy/client_credentials_spec.rb b/spec/oauth2/strategy/client_credentials_spec.rb
index 1c440c9b..e5b800e7 100644
--- a/spec/oauth2/strategy/client_credentials_spec.rb
+++ b/spec/oauth2/strategy/client_credentials_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 describe OAuth2::Strategy::ClientCredentials do
   subject { client.client_credentials }
 
diff --git a/spec/oauth2/strategy/implicit_spec.rb b/spec/oauth2/strategy/implicit_spec.rb
index c4df8ebd..72042120 100644
--- a/spec/oauth2/strategy/implicit_spec.rb
+++ b/spec/oauth2/strategy/implicit_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 describe OAuth2::Strategy::Implicit do
   subject { client.implicit }
 
diff --git a/spec/oauth2/strategy/password_spec.rb b/spec/oauth2/strategy/password_spec.rb
index f46c9f0f..e6084740 100644
--- a/spec/oauth2/strategy/password_spec.rb
+++ b/spec/oauth2/strategy/password_spec.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
 describe OAuth2::Strategy::Password do
   subject { client.password }
 

From b236d5b472ac9aad64a92ed9fa6a2c2538b20e08 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Sun, 20 Feb 2022 14:58:19 +0700
Subject: [PATCH 119/163] =?UTF-8?q?=E2=9E=96=20Remove=20backports=20gem=20?=
 =?UTF-8?q?dependency?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 CHANGELOG.md   | 9 +++++++++
 oauth2.gemspec | 1 -
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 689df016..c24d4d69 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,6 +3,15 @@ All notable changes to this project will be documented in this file.
 
 ## unreleased
 
+## [1.4.9] - 2022-02-20
+
+- Fixes compatibility with Faraday v2 [572](https://github.com/oauth-xx/oauth2/issues/572)
+- Includes supported versions of Faraday in test matrix:
+  - Faraday ~> 2.2.0 with Ruby >= 2.6
+  - Faraday ~> 1.10 with Ruby >= 2.4
+  - Faraday ~> 0.17.3 with Ruby >= 1.9
+- Add Windows and MacOS to test matrix
+
 ## [1.4.8] - 2022-02-18
 
 - MFA is now required to push new gem versions (@pboling)
diff --git a/oauth2.gemspec b/oauth2.gemspec
index 4c35df62..b6ee8cce 100644
--- a/oauth2.gemspec
+++ b/oauth2.gemspec
@@ -39,7 +39,6 @@ Gem::Specification.new do |spec|
   spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
 
   spec.add_development_dependency 'addressable', '~> 2.3'
-  spec.add_development_dependency 'backports', '~> 3.11'
   spec.add_development_dependency 'bundler', '>= 1.16'
   spec.add_development_dependency 'rake', '~> 12.3'
   spec.add_development_dependency 'rexml', '~> 3.2'

From 9105b39e08c4310a144519dafc392a7783876b70 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Sun, 20 Feb 2022 14:59:53 +0700
Subject: [PATCH 120/163] =?UTF-8?q?=F0=9F=94=96=20Release=201.4.9?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 lib/oauth2/version.rb | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/oauth2/version.rb b/lib/oauth2/version.rb
index 4d91969b..88cf98dc 100644
--- a/lib/oauth2/version.rb
+++ b/lib/oauth2/version.rb
@@ -24,7 +24,7 @@ def minor
     #
     # @return [Integer]
     def patch
-      8
+      9
     end
 
     # The pre-release version, if any

From 39b05b46fd45886dcaf0bec4a5c8824852ca9d07 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Sun, 20 Feb 2022 22:47:08 +0700
Subject: [PATCH 121/163] =?UTF-8?q?=F0=9F=93=9D=20Link=20release=201.4.9?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 CHANGELOG.md | 1 +
 README.md    | 1 +
 2 files changed, 2 insertions(+)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index c24d4d69..988fe754 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -193,4 +193,5 @@ All notable changes to this project will be documented in this file.
 [1.4.6]: https://github.com/oauth-xx/oauth2/compare/v1.4.5...v1.4.6
 [1.4.7]: https://github.com/oauth-xx/oauth2/compare/v1.4.6...v1.4.7
 [1.4.8]: https://github.com/oauth-xx/oauth2/compare/v1.4.7...v1.4.8
+[1.4.9]: https://github.com/oauth-xx/oauth2/compare/v1.4.8...v1.4.9
 [unreleased]: https://github.com/oauth-xx/oauth2/compare/v1.4.1...HEAD
diff --git a/README.md b/README.md
index f5e83496..96eb7817 100644
--- a/README.md
+++ b/README.md
@@ -38,6 +38,7 @@ branch which for version 1.4.x releases. Version 2.0 is coming! ⚠️
 
 | Version | Release Date | Readme                                                   |
 |---------|--------------|----------------------------------------------------------|
+| 1.4.9   | Feb 20, 2022 | https://github.com/oauth-xx/oauth2/blob/v1.4.9/README.md |
 | 1.4.8   | Feb 18, 2022 | https://github.com/oauth-xx/oauth2/blob/v1.4.8/README.md |
 | 1.4.7   | Mar 19, 2021 | https://github.com/oauth-xx/oauth2/blob/v1.4.7/README.md |
 | 1.4.6   | Mar 19, 2021 | https://github.com/oauth-xx/oauth2/blob/v1.4.6/README.md |

From 007973891323e8f38c5e3e2e9e66b7a97030d676 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Mon, 21 Feb 2022 00:52:02 +0700
Subject: [PATCH 122/163] =?UTF-8?q?=F0=9F=93=9D=20Badge=20Fixes?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 README.md | 54 +++++++++++++++++++++++++++++++-----------------------
 1 file changed, 31 insertions(+), 23 deletions(-)

diff --git a/README.md b/README.md
index 96eb7817..48b4235a 100644
--- a/README.md
+++ b/README.md
@@ -94,15 +94,15 @@ badge #s:
 📗
 -->
 
-|     | Project               | oauth2                                                                                                                                                                                                                                                              |
-|:----|-----------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| 1️⃣ | name, license, docs   | [![RubyGems.org][⛳️name-img]][⛳️gem] [![License: MIT][🖇src-license-img]][🖇src-license] [![FOSSA][🏘fossa-img]][🏘fossa] [![RubyDoc.info][🚎yard-img]][🚎yard] [![InchCI][🖐inch-ci-img]][🚎yard]                                                                  |
-| 2️⃣ | version & activity    | [![Gem Version][⛳️version-img]][⛳️gem] [![Total Downloads][🖇DL-total-img]][⛳️gem] [![Download Rank][🏘DL-rank-img]][⛳️gem] [![Source Code][🚎src-home-img]][🚎src-home] [![Open PRs][🖐prs-open-img]][🖐prs-open] [![Closed PRs][🧮prs-closed-img]][🧮prs-closed]  |
-| 3️⃣ | maintanence & linting | [![Maintainability][⛳cclim-maint-img]][⛳cclim-maint] [![Helpers][🖇triage-help-img]][🖇triage-help] [![Depfu][🏘depfu-img]][🏘depfu] [![Contributors][🚎contributors-img]][🚎contributors] [![Style][🖐style-wf-img]][🖐style-wf] [![Kloc Roll][🧮kloc-img]][🧮kloc] |
-| 4️⃣ | testing               | [![Build][⛳️tot-bld-img]][⛳️tot-bld] [![supported][🖇supported-wf-img]][🖇supported-wf] [![EOL & Code Coverage Build][🏘eol-wf-img]][🏘eol-wf] [![unsupported][🚎unsupported-wf-img]][🚎unsupported-wf]                                                             |
-| 5️⃣ | coverage & security   | [![CodeClimate][⛳cclim-cov-img]][⛳cclim-cov] [![CodeCov][🖇codecov-img]][🖇codecov] [![Coveralls][🏘coveralls-img]][🏘coveralls] [![Security Policy][🚎sec-pol-img]][🚎sec-pol] [![CodeQL][🖐codeQL-img]][🖐codeQL]                                                 |
-| 6️⃣ | resources             | [![Discussion][⛳gh-discussions-img]][⛳gh-discussions] [![Get help on Codementor][🖇codementor-img]][🖇codementor] [![Chat][🏘chat-img]][🏘chat] [![Blog][🚎blog-img]][🚎blog] [![Blog][🖐wiki-img]][🖐wiki]                                                         |
-| 7️⃣ | spread 💖             | [![Liberapay Patrons][⛳liberapay-img]][⛳liberapay] [![Sponsor Me][🖇sponsor-img]][🖇sponsor] [![Tweet @ Peter][🏘tweet-img]][🏘tweet] [🌏][aboutme] [👼][angelme] [💻][coderme] [🌹][politicme]                                                                     |
+|     | Project               | oauth2                                                                                                                                                                                                                                                                                   |
+|:----|-----------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| 1️⃣ | name, license, docs   | [![RubyGems.org][⛳️name-img]][⛳️gem] [![License: MIT][🖇src-license-img]][🖇src-license] [![FOSSA][🏘fossa-img]][🏘fossa] [![RubyDoc.info][🚎yard-img]][🚎yard] [![InchCI][🖐inch-ci-img]][🚎yard]                                                                                       |
+| 2️⃣ | version & activity    | [![Gem Version][⛳️version-img]][⛳️gem] [![Total Downloads][🖇DL-total-img]][⛳️gem] [![Download Rank][🏘DL-rank-img]][⛳️gem] [![Source Code][🚎src-home-img]][🚎src-home] [![Open PRs][🖐prs-o-img]][🖐prs-o] [![Closed PRs][🧮prs-c-img]][🧮prs-c] [![Next Version][📗next-img]][📗next] |
+| 3️⃣ | maintanence & linting | [![Maintainability][⛳cclim-maint-img]][⛳cclim-maint] [![Helpers][🖇triage-help-img]][🖇triage-help] [![Depfu][🏘depfu-img]][🏘depfu] [![Contributors][🚎contributors-img]][🚎contributors] [![Style][🖐style-wf-img]][🖐style-wf] [![Kloc Roll][🧮kloc-img]][🧮kloc]                     |
+| 4️⃣ | testing               | [![Open Issues][⛳iss-o-img]][⛳iss-o] [![Closed Issues][🖇iss-c-img]][🖇iss-c] [![Supported][🏘sup-wf-img]][🏘sup-wf] [![Heads][🚎heads-wf-img]][🚎heads-wf] [![Unofficial Support][🖐uns-wf-img]][🖐uns-wf] [![MacOS][🧮mac-wf-img]][🧮mac-wf] [![Windows][📗win-wf-img]][📗win-wf]      |
+| 5️⃣ | coverage & security   | [![CodeClimate][⛳cclim-cov-img]][⛳cclim-cov] [![CodeCov][🖇codecov-img]][🖇codecov] [![Coveralls][🏘coveralls-img]][🏘coveralls] [![Security Policy][🚎sec-pol-img]][🚎sec-pol] [![CodeQL][🖐codeQL-img]][🖐codeQL] [![Code Coverage][🏘cov-wf-img]][🏘cov-wf]                           |
+| 6️⃣ | resources             | [![Discussion][⛳gh-discussions-img]][⛳gh-discussions] [![Get help on Codementor][🖇codementor-img]][🖇codementor] [![Chat][🏘chat-img]][🏘chat] [![Blog][🚎blog-img]][🚎blog] [![Blog][🖐wiki-img]][🖐wiki]                                                                              |
+| 7️⃣ | spread 💖             | [![Liberapay Patrons][⛳liberapay-img]][⛳liberapay] [![Sponsor Me][🖇sponsor-img]][🖇sponsor] [![Tweet @ Peter][🏘tweet-img]][🏘tweet] [🌏][aboutme] [👼][angelme] [💻][coderme] [🌹][politicme]                                                                                          |
 
 <!--
 The link tokens in the following sections should be kept ordered by the row and badge numbering scheme
@@ -125,10 +125,12 @@ The link tokens in the following sections should be kept ordered by the row and
 [🏘DL-rank-img]: https://img.shields.io/gem/rt/oauth2.svg
 [🚎src-home]: https://github.com/oauth-xx/oauth2
 [🚎src-home-img]: https://img.shields.io/badge/source-github-brightgreen.svg?style=flat
-[🖐prs-open]: https://github.com/oauth-xx/oauth2/pulls
-[🖐prs-open-img]: https://img.shields.io/github/issues-pr/oauth-xx/oauth2
-[🧮prs-closed]: https://github.com/oauth-xx/oauth2/pulls?q=is%3Apr+is%3Aclosed
-[🧮prs-closed-img]: https://img.shields.io/github/issues-pr-closed/oauth-xx/oauth2
+[🖐prs-o]: https://github.com/oauth-xx/oauth2/pulls
+[🖐prs-o-img]: https://img.shields.io/github/issues-pr/oauth-xx/oauth2
+[🧮prs-c]: https://github.com/oauth-xx/oauth2/pulls?q=is%3Apr+is%3Aclosed
+[🧮prs-c-img]: https://img.shields.io/github/issues-pr-closed/oauth-xx/oauth2
+[📗next]: https://github.com/oauth-xx/oauth2/milestone/1
+[📗next-img]: https://img.shields.io/github/milestones/progress/oauth-xx/oauth2/1?label=Next%20Version
 
 <!-- 3️⃣ maintanence & linting -->
 [⛳cclim-maint]: https://codeclimate.com/github/oauth-xx/oauth2/maintainability
@@ -145,16 +147,20 @@ The link tokens in the following sections should be kept ordered by the row and
 [🧮kloc-img]: https://img.shields.io/tokei/lines/github.com/oauth-xx/oauth2
 
 <!-- 4️⃣ testing -->
-[⛳️tot-bld]: https://actions-badge.atrox.dev/oauth-xx/oauth2/goto
-[⛳️tot-bld-img]: https://img.shields.io/endpoint.svg?url=https%3A%2F%2Factions-badge.atrox.dev%2Foauth-xx%2Foauth2%2Fbadge&style=flat
-[🖇supported-wf]: https://github.com/oauth-xx/oauth2/actions/workflows/supported.yml
-[🖇supported-wf-img]: https://github.com/oauth-xx/oauth2/actions/workflows/supported.yml/badge.svg
-[🏘eol-wf]: https://github.com/oauth-xx/oauth2/actions/workflows/coverage.yml
-[🏘eol-wf-img]: https://github.com/oauth-xx/oauth2/actions/workflows/coverage.yml/badge.svg
-[🚎unsupported-wf]: https://github.com/oauth-xx/oauth2/actions/workflows/unsupported.yml
-[🚎unsupported-wf-img]: https://github.com/oauth-xx/oauth2/actions/workflows/unsupported.yml/badge.svg
-[🖐issues]: https://github.com/oauth-xx/oauth2/issues
-[🖐issues-img]: https://github.com/oauth-xx/oauth2/issues
+[⛳iss-o]: https://github.com/oauth-xx/oauth2/issues
+[⛳iss-o-img]: https://img.shields.io/github/issues-raw/oauth-xx/oauth2
+[🖇iss-c]: https://github.com/oauth-xx/oauth2/issues?q=is%3Aissue+is%3Aclosed
+[🖇iss-c-img]: https://img.shields.io/github/issues-closed-raw/oauth-xx/oauth2
+[🏘sup-wf]: https://github.com/oauth-xx/oauth2/actions/workflows/supported.yml
+[🏘sup-wf-img]: https://github.com/oauth-xx/oauth2/actions/workflows/supported.yml/badge.svg
+[🚎heads-wf]: https://github.com/oauth-xx/oauth2/actions/workflows/heads.yml
+[🚎heads-wf-img]: https://github.com/oauth-xx/oauth2/actions/workflows/heads.yml/badge.svg
+[🖐uns-wf]: https://github.com/oauth-xx/oauth2/actions/workflows/unsupported.yml
+[🖐uns-wf-img]: https://github.com/oauth-xx/oauth2/actions/workflows/unsupported.yml/badge.svg
+[🧮mac-wf]: https://github.com/oauth-xx/oauth2/actions/workflows/macos.yml
+[🧮mac-wf-img]: https://github.com/oauth-xx/oauth2/actions/workflows/macos.yml/badge.svg
+[📗win-wf]: https://github.com/oauth-xx/oauth2/actions/workflows/windows.yml
+[📗win-wf-img]: https://github.com/oauth-xx/oauth2/actions/workflows/windows.yml/badge.svg
 
 <!-- 5️⃣ coverage & security -->
 [⛳cclim-cov]: https://codeclimate.com/github/oauth-xx/oauth2/test_coverage
@@ -167,6 +173,8 @@ The link tokens in the following sections should be kept ordered by the row and
 [🚎sec-pol-img]: https://img.shields.io/badge/security-policy-brightgreen.svg?style=flat
 [🖐codeQL]: https://github.com/oauth-xx/oauth2/security/code-scanning
 [🖐codeQL-img]: https://github.com/oauth-xx/oauth2/actions/workflows/codeql-analysis.yml/badge.svg
+[🧮cov-wf]: https://github.com/oauth-xx/oauth2/actions/workflows/coverage.yml
+[🧮cov-wf-img]: https://github.com/oauth-xx/oauth2/actions/workflows/coverage.yml/badge.svg
 
 <!-- 6️⃣ resources -->
 [⛳gh-discussions]: https://github.com/oauth-xx/oauth2/discussions

From ff0d79b652f0c51292a1b1e5f3e55de497de5b12 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Mon, 21 Feb 2022 00:54:20 +0700
Subject: [PATCH 123/163] =?UTF-8?q?=F0=9F=93=9D=20Badge=20Fixes?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.md b/README.md
index 48b4235a..ac9f8bfc 100644
--- a/README.md
+++ b/README.md
@@ -100,7 +100,7 @@ badge #s:
 | 2️⃣ | version & activity    | [![Gem Version][⛳️version-img]][⛳️gem] [![Total Downloads][🖇DL-total-img]][⛳️gem] [![Download Rank][🏘DL-rank-img]][⛳️gem] [![Source Code][🚎src-home-img]][🚎src-home] [![Open PRs][🖐prs-o-img]][🖐prs-o] [![Closed PRs][🧮prs-c-img]][🧮prs-c] [![Next Version][📗next-img]][📗next] |
 | 3️⃣ | maintanence & linting | [![Maintainability][⛳cclim-maint-img]][⛳cclim-maint] [![Helpers][🖇triage-help-img]][🖇triage-help] [![Depfu][🏘depfu-img]][🏘depfu] [![Contributors][🚎contributors-img]][🚎contributors] [![Style][🖐style-wf-img]][🖐style-wf] [![Kloc Roll][🧮kloc-img]][🧮kloc]                     |
 | 4️⃣ | testing               | [![Open Issues][⛳iss-o-img]][⛳iss-o] [![Closed Issues][🖇iss-c-img]][🖇iss-c] [![Supported][🏘sup-wf-img]][🏘sup-wf] [![Heads][🚎heads-wf-img]][🚎heads-wf] [![Unofficial Support][🖐uns-wf-img]][🖐uns-wf] [![MacOS][🧮mac-wf-img]][🧮mac-wf] [![Windows][📗win-wf-img]][📗win-wf]      |
-| 5️⃣ | coverage & security   | [![CodeClimate][⛳cclim-cov-img]][⛳cclim-cov] [![CodeCov][🖇codecov-img]][🖇codecov] [![Coveralls][🏘coveralls-img]][🏘coveralls] [![Security Policy][🚎sec-pol-img]][🚎sec-pol] [![CodeQL][🖐codeQL-img]][🖐codeQL] [![Code Coverage][🏘cov-wf-img]][🏘cov-wf]                           |
+| 5️⃣ | coverage & security   | [![CodeClimate][⛳cclim-cov-img]][⛳cclim-cov] [![CodeCov][🖇codecov-img]][🖇codecov] [![Coveralls][🏘coveralls-img]][🏘coveralls] [![Security Policy][🚎sec-pol-img]][🚎sec-pol] [![CodeQL][🖐codeQL-img]][🖐codeQL] [![Code Coverage][🧮cov-wf-img]][🧮cov-wf]                           |
 | 6️⃣ | resources             | [![Discussion][⛳gh-discussions-img]][⛳gh-discussions] [![Get help on Codementor][🖇codementor-img]][🖇codementor] [![Chat][🏘chat-img]][🏘chat] [![Blog][🚎blog-img]][🚎blog] [![Blog][🖐wiki-img]][🖐wiki]                                                                              |
 | 7️⃣ | spread 💖             | [![Liberapay Patrons][⛳liberapay-img]][⛳liberapay] [![Sponsor Me][🖇sponsor-img]][🖇sponsor] [![Tweet @ Peter][🏘tweet-img]][🏘tweet] [🌏][aboutme] [👼][angelme] [💻][coderme] [🌹][politicme]                                                                                          |
 

From cf5b28e32714d0d747c28a3a6314d50643003879 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Mon, 21 Feb 2022 01:16:36 +0700
Subject: [PATCH 124/163] =?UTF-8?q?=E2=9E=96=20Remove=20unused=20developme?=
 =?UTF-8?q?nt=20dependencies?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 Gemfile | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/Gemfile b/Gemfile
index e4884b03..730d3937 100644
--- a/Gemfile
+++ b/Gemfile
@@ -6,14 +6,10 @@ gemspec
 
 git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
 
-gem 'jwt'
 gem 'overcommit'
-gem 'rake'
 
 group :test do
-  gem 'addressable', '~> 2.3.8'
-  gem 'backports'
-  gem 'rack', '~> 1.2', :platforms => [:ruby_21]
+  gem 'addressable', '>= 2.3'
   gem 'rspec', '>= 3'
   platforms :mri do
     ruby_version = Gem::Version.new(RUBY_VERSION)

From f88d187b9571927485db2f24939f5d4d9830cc97 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Mon, 21 Feb 2022 01:18:47 +0700
Subject: [PATCH 125/163] =?UTF-8?q?=F0=9F=93=8C=20Loosen=20dependency=20on?=
 =?UTF-8?q?=20rake?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 oauth2.gemspec | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/oauth2.gemspec b/oauth2.gemspec
index b6ee8cce..003b56d5 100644
--- a/oauth2.gemspec
+++ b/oauth2.gemspec
@@ -40,7 +40,7 @@ Gem::Specification.new do |spec|
 
   spec.add_development_dependency 'addressable', '~> 2.3'
   spec.add_development_dependency 'bundler', '>= 1.16'
-  spec.add_development_dependency 'rake', '~> 12.3'
+  spec.add_development_dependency 'rake', '>= 12.3'
   spec.add_development_dependency 'rexml', '~> 3.2'
   spec.add_development_dependency 'rspec', '~> 3.0'
   spec.add_development_dependency 'rspec-block_is_expected'

From bc54618f91bab353b5837df5bff5b26f7bc5cd85 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Mon, 21 Feb 2022 01:53:54 +0700
Subject: [PATCH 126/163] =?UTF-8?q?=F0=9F=8E=A8=20Normalize=20Compat=20Tab?=
 =?UTF-8?q?le?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 README.md | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/README.md b/README.md
index ac9f8bfc..b85699d9 100644
--- a/README.md
+++ b/README.md
@@ -258,8 +258,8 @@ of a major release, support for that Ruby version may be dropped.
 
 |     | Ruby OAuth 2 Version | Maintenance Branch | Supported Officially    | Supported Unofficially | Supported Incidentally |
 |:----|----------------------|--------------------|-------------------------|------------------------|------------------------|
-| 1️⃣ | 2.0.x (unreleased)   | `master`           | 2.7, 3.0, 3.1           | 2.6, 2.5               | 2.4, 2.3, 2.2          |
-| 2️⃣ | 1.4.x                | `1-4-stable`       | 2.5, 2.6, 2.7, 3.0, 3.1 | 2.1, 2.2, 2.3, 2.4     | 2.0, 1.9               |
+| 1️⃣ | 2.0.x (unreleased)   | `master`           | 2.7, 3.0, 3.1           | 2.5, 2.6               | 2.2, 2.3, 2.4          |
+| 2️⃣ | 1.4.x                | `1-4-stable`       | 2.5, 2.6, 2.7, 3.0, 3.1 | 2.1, 2.2, 2.3, 2.4     | 1.9, 2.0               |
 | 3️⃣ | older                | N/A                | Best of luck to you!    | Please upgrade!        |                        |
 
 NOTE: Once 2.0 is released, the 1.4 series will only receive critical bug and security updates.

From 2cf5947938122272acb3c4e4393c2dc95d85c4ff Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Tue, 3 May 2022 07:00:18 +0700
Subject: [PATCH 127/163] =?UTF-8?q?=F0=9F=92=9A=20Do=20not=20install=20lib?=
 =?UTF-8?q?curl4-openssl-dev?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 .github/workflows/coverage.yml    | 3 ---
 .github/workflows/danger.yml      | 2 --
 .github/workflows/heads.yml       | 2 --
 .github/workflows/style.yml       | 2 --
 .github/workflows/supported.yml   | 2 --
 .github/workflows/unsupported.yml | 2 --
 6 files changed, 13 deletions(-)

diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml
index c3c94a5c..82f42f44 100644
--- a/.github/workflows/coverage.yml
+++ b/.github/workflows/coverage.yml
@@ -44,9 +44,6 @@ jobs:
     runs-on: ubuntu-latest
     continue-on-error: ${{ matrix.experimental || endsWith(matrix.ruby, 'head') }}
     steps:
-      - name: Install cURL Headers
-        run: sudo apt-get install libcurl4-openssl-dev
-
       - uses: amancevice/setup-code-climate@v0
         name: CodeClimate Install
         if: matrix.ruby == '2.7' && github.event_name != 'pull_request' && always()
diff --git a/.github/workflows/danger.yml b/.github/workflows/danger.yml
index 7723f57c..ab63ab1c 100644
--- a/.github/workflows/danger.yml
+++ b/.github/workflows/danger.yml
@@ -28,8 +28,6 @@ jobs:
     steps:
       - name: Checkout
         uses: actions/checkout@v2
-      - name: Install cURL Headers
-        run: sudo apt-get install libcurl4-openssl-dev
       - name: Setup Ruby & Bundle
         uses: ruby/setup-ruby@v1
         with:
diff --git a/.github/workflows/heads.yml b/.github/workflows/heads.yml
index 6dece37c..d56fa8b9 100644
--- a/.github/workflows/heads.yml
+++ b/.github/workflows/heads.yml
@@ -60,8 +60,6 @@ jobs:
     steps:
       - name: Checkout
         uses: actions/checkout@v2
-      - name: Install cURL Headers
-        run: sudo apt-get install libcurl4-openssl-dev
       - name: Setup Ruby & Bundle
         uses: ruby/setup-ruby@v1
         with:
diff --git a/.github/workflows/style.yml b/.github/workflows/style.yml
index 22c5ac70..5c4c219d 100644
--- a/.github/workflows/style.yml
+++ b/.github/workflows/style.yml
@@ -32,8 +32,6 @@ jobs:
     steps:
       - name: Checkout
         uses: actions/checkout@v2
-      - name: Install cURL Headers
-        run: sudo apt-get install libcurl4-openssl-dev
       - name: Setup Ruby & Bundle
         uses: ruby/setup-ruby@v1
         with:
diff --git a/.github/workflows/supported.yml b/.github/workflows/supported.yml
index b0e3b5a6..493c11bc 100644
--- a/.github/workflows/supported.yml
+++ b/.github/workflows/supported.yml
@@ -52,8 +52,6 @@ jobs:
     steps:
       - name: Checkout
         uses: actions/checkout@v2
-      - name: Install cURL Headers
-        run: sudo apt-get install libcurl4-openssl-dev
       - name: Setup Ruby & Bundle
         uses: ruby/setup-ruby@v1
         with:
diff --git a/.github/workflows/unsupported.yml b/.github/workflows/unsupported.yml
index 3b4ee3fb..f7670f68 100644
--- a/.github/workflows/unsupported.yml
+++ b/.github/workflows/unsupported.yml
@@ -60,8 +60,6 @@ jobs:
     steps:
       - name: Checkout
         uses: actions/checkout@v2
-      - name: Install cURL Headers
-        run: sudo apt-get install libcurl4-openssl-dev
       - name: Setup Ruby & Bundle
         uses: ruby/setup-ruby@v1
         with:

From f82a7e1e450192b17bd1053ea9aec0225138022e Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Tue, 3 May 2022 07:12:47 +0700
Subject: [PATCH 128/163] =?UTF-8?q?=F0=9F=94=A5=20Prefer=20.tool-versions?=
 =?UTF-8?q?=20over=20.ruby-version?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 .ruby-version | 1 -
 1 file changed, 1 deletion(-)
 delete mode 100644 .ruby-version

diff --git a/.ruby-version b/.ruby-version
deleted file mode 100644
index 24ba9a38..00000000
--- a/.ruby-version
+++ /dev/null
@@ -1 +0,0 @@
-2.7.0

From 9e7b4c99be77e8318541c2b57728202bc773b06e Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Tue, 3 May 2022 08:10:09 +0700
Subject: [PATCH 129/163] =?UTF-8?q?=E2=9E=95=20rubocop-ruby1=5F9?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 .rubocop.yml               | 88 +++++++++++++++++++-------------------
 .rubocop_rspec.yml         |  4 ++
 .rubocop_todo.yml          | 71 +++---------------------------
 Gemfile                    | 13 ++----
 lib/oauth2/client.rb       |  4 +-
 spec/oauth2/client_spec.rb | 10 ++---
 6 files changed, 62 insertions(+), 128 deletions(-)

diff --git a/.rubocop.yml b/.rubocop.yml
index 81f22bf8..c520c40e 100644
--- a/.rubocop.yml
+++ b/.rubocop.yml
@@ -1,53 +1,57 @@
-inherit_from:
-  - .rubocop_todo.yml
-  - .rubocop_rspec.yml
+inherit_gem:
+  rubocop-ruby1_9: rubocop.yml
 
 require:
-  - 'rubocop-md'
-  - 'rubocop-packaging'
-  - 'rubocop-performance'
-  - 'rubocop-rake'
   - 'rubocop-rspec'
+  - 'rubocop-thread_safety'
+
+inherit_from:
+  - .rubocop_todo.yml
+  - .rubocop_rspec.yml
 
 AllCops:
-  NewCops: enable
   DisplayCopNames: true # Display the name of the failing cops
-  TargetRubyVersion: 2.5
   Exclude:
     - 'gemfiles/vendor/**/*'
     - 'vendor/**/*'
     - '**/.irbrc'
 
-Metrics/BlockLength:
-  IgnoredMethods:
-    - context
-    - describe
-    - it
-    - shared_context
-    - shared_examples
-    - shared_examples_for
-    - namespace
-    - draw
-
-Gemspec/RequiredRubyVersion:
-  Enabled: false
+#Metrics/BlockLength:
+#  IgnoredMethods:
+#    - context
+#    - describe
+#    - it
+#    - shared_context
+#    - shared_examples
+#    - shared_examples_for
+#    - namespace
+#    - draw
+
+#Gemspec/RequiredRubyVersion:
+#  Enabled: false
+
+Style/PercentLiteralDelimiters:
+  PreferredDelimiters:
+    default: '[]'
+    '%i':    '()'
+    '%w':    '[]'
 
 Metrics/BlockNesting:
   Max: 2
 
-Layout/LineLength:
+Metrics/LineLength:
   Enabled: false
 
 Metrics/ParameterLists:
   Max: 4
 
-Layout/AccessModifierIndentation:
+Style/AccessModifierIndentation:
   EnforcedStyle: outdent
 
-Layout/DotPosition:
+Style/DotPosition:
   EnforcedStyle: trailing
 
-Layout/SpaceInsideHashLiteralBraces:
+Style/SpaceInsideHashLiteralBraces:
   EnforcedStyle: no_space
 
 Lint/UnusedBlockArgument:
@@ -57,13 +61,6 @@ Lint/UnusedBlockArgument:
     - 'vendor/**/*'
     - '**/.irbrc'
 
-RSpec/DescribeClass:
-  Exclude:
-    - 'spec/examples/*'
-
-RSpec/NestedGroups:
-  Enabled: false
-
 Style/ClassVars:
   Enabled: false
 
@@ -80,17 +77,20 @@ Style/Documentation:
 Style/DoubleNegation:
   Enabled: false
 
-Style/EmptyMethod:
-  EnforcedStyle: expanded
+#Style/EmptyMethod:
+#  EnforcedStyle: expanded
 
 Style/Encoding:
   Enabled: false
 
-Style/TrailingCommaInArrayLiteral:
+Style/TrailingCommaInLiteral:
   EnforcedStyleForMultiline: comma
 
-Style/TrailingCommaInHashLiteral:
-  EnforcedStyleForMultiline: comma
+#Style/TrailingCommaInArrayLiteral:
+#  EnforcedStyleForMultiline: comma
+#
+#Style/TrailingCommaInHashLiteral:
+#  EnforcedStyleForMultiline: comma
 
 Style/HashSyntax:
   EnforcedStyle: hash_rockets
@@ -105,16 +105,16 @@ Style/EachWithObject:
   Enabled: false
 
 # Once we drop Rubies that lack support for __dir__ we can turn this on.
-Style/ExpandPathArguments:
-  Enabled: false
+#Style/ExpandPathArguments:
+#  Enabled: false
 
 # On Ruby 1.9 array.to_h isn't available, needs to be Hash[array]
-Style/HashConversion:
-  Enabled: false
+#Style/HashConversion:
+#  Enabled: false
 
 # Turn back on once old Rubies are dropped
 Style/IfUnlessModifier:
   Enabled: false
 
-Style/SafeNavigation:
-  Enabled: false
+#Style/SafeNavigation:
+#  Enabled: false
diff --git a/.rubocop_rspec.yml b/.rubocop_rspec.yml
index 48ad1a31..b8ab6fa1 100644
--- a/.rubocop_rspec.yml
+++ b/.rubocop_rspec.yml
@@ -1,3 +1,7 @@
+RSpec/DescribeClass:
+  Exclude:
+    - 'spec/examples/*'
+
 RSpec/FilePath:
   Enabled: false
 
diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml
index bae0df7a..64def32c 100644
--- a/.rubocop_todo.yml
+++ b/.rubocop_todo.yml
@@ -1,90 +1,29 @@
 # This configuration was generated by
 # `rubocop --auto-gen-config`
-# on 2022-02-20 04:57:56 UTC using RuboCop version 1.25.1.
+# on 2022-05-03 08:04:37 +0700 using RuboCop version 0.41.2.
 # The point is for the user to remove these configuration records
 # one by one as the offenses are removed from the code base.
 # Note that changes in the inspected code, or installation of new
 # versions of RuboCop, may require this file to be generated again.
 
-# Offense count: 1
-# Configuration parameters: AllowedMethods.
-# AllowedMethods: enums
-Lint/ConstantDefinitionInBlock:
-  Exclude:
-    - 'spec/oauth2/client_spec.rb'
-
 # Offense count: 1
 Lint/UselessAssignment:
   Exclude:
-    - '**/*.md'
-    - '**/*.markdown'
     - 'spec/oauth2/client_spec.rb'
 
 # Offense count: 4
-# Configuration parameters: IgnoredMethods, CountRepeatedAttributes.
 Metrics/AbcSize:
-  Max: 43
+  Max: 39
 
-# Offense count: 4
-# Configuration parameters: CountComments, CountAsOne, ExcludedMethods, IgnoredMethods.
-# IgnoredMethods: refine
-Metrics/BlockLength:
-  Max: 59
-
-# Offense count: 2
-# Configuration parameters: IgnoredMethods.
+# Offense count: 1
 Metrics/CyclomaticComplexity:
   Max: 11
 
 # Offense count: 8
-# Configuration parameters: CountComments, CountAsOne, ExcludedMethods, IgnoredMethods.
+# Configuration parameters: CountComments.
 Metrics/MethodLength:
   Max: 37
 
 # Offense count: 1
-# Configuration parameters: IgnoredMethods.
 Metrics/PerceivedComplexity:
-  Max: 11
-
-# Offense count: 1
-# Configuration parameters: EnforcedStyle, CheckMethodNames, CheckSymbols, AllowedIdentifiers.
-# SupportedStyles: snake_case, normalcase, non_integer
-# AllowedIdentifiers: capture3, iso8601, rfc1123_date, rfc822, rfc2822, rfc3339
-Naming/VariableNumber:
-  Exclude:
-    - 'Gemfile'
-
-# Offense count: 2
-# Configuration parameters: MinSize.
-Performance/CollectionLiteralInLoop:
-  Exclude:
-    - 'spec/oauth2/strategy/auth_code_spec.rb'
-    - 'spec/oauth2/strategy/client_credentials_spec.rb'
-
-# Offense count: 7
-# Configuration parameters: Prefixes.
-# Prefixes: when, with, without
-RSpec/ContextWording:
-  Exclude:
-    - 'spec/oauth2/access_token_spec.rb'
-    - 'spec/oauth2/authenticator_spec.rb'
-    - 'spec/oauth2/client_spec.rb'
-
-# Offense count: 1
-RSpec/LeakyConstantDeclaration:
-  Exclude:
-    - 'spec/oauth2/client_spec.rb'
-
-# Offense count: 1
-# Cop supports --auto-correct.
-Rake/Desc:
-  Exclude:
-    - 'Rakefile'
-
-# Offense count: 3
-# Cop supports --auto-correct-all.
-# Configuration parameters: Mode.
-Style/StringConcatenation:
-  Exclude:
-    - 'lib/oauth2/authenticator.rb'
-    - 'spec/oauth2/authenticator_spec.rb'
+  Max: 14
diff --git a/Gemfile b/Gemfile
index 730d3937..924fbfc3 100644
--- a/Gemfile
+++ b/Gemfile
@@ -18,16 +18,9 @@ group :test do
     coverage = minimum_version.call('2.7')
     debug = minimum_version.call('2.5')
     if linting
-      # Danger is incompatible with Faraday 2 (for now)
-      # see: https://github.com/danger/danger/issues/1349
-      # gem 'danger', '~> 8.4'
-      gem 'rubocop', '~> 1.22', :require => false
-      gem 'rubocop-md', '~> 1.0', :require => false
-      gem 'rubocop-packaging', '~> 0.5', :require => false
-      gem 'rubocop-performance', '~> 1.11', :require => false
-      gem 'rubocop-rake', '~> 0.6', :require => false
-      gem 'rubocop-rspec', :require => false
-      gem 'rubocop-thread_safety', '~> 0.4', :require => false
+      gem 'rubocop-ruby1_9', '~> 1.0', :require => false
+      gem 'rubocop-rspec', '1.5.0', :require => false
+      gem 'rubocop-thread_safety', '0.3.1', :require => false
     end
     if coverage
       gem 'codecov', :require => false, :group => :test
diff --git a/lib/oauth2/client.rb b/lib/oauth2/client.rb
index 611dab24..e6160c53 100644
--- a/lib/oauth2/client.rb
+++ b/lib/oauth2/client.rb
@@ -100,7 +100,7 @@ def token_url(params = nil)
     #   code response for this request.  Will default to client option
     # @option opts [Symbol] :parse @see Response::initialize
     # @yield [req] The Faraday request
-    def request(verb, url, opts = {}) # rubocop:disable Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity, Metrics/AbcSize
+    def request(verb, url, opts = {}) # rubocop:disable Metrics/AbcSize
       url = connection.build_url(url).to_s
 
       begin
@@ -185,7 +185,7 @@ def get_token(params, access_token_opts = {}, extract_access_token = options[:ex
       response_contains_token = access_token || (
                                   response.parsed.is_a?(Hash) &&
                                   (response.parsed['access_token'] || response.parsed['id_token'])
-                                )
+      )
 
       if options[:raise_errors] && !response_contains_token
         error = Error.new(response)
diff --git a/spec/oauth2/client_spec.rb b/spec/oauth2/client_spec.rb
index d5884264..a27cda83 100644
--- a/spec/oauth2/client_spec.rb
+++ b/spec/oauth2/client_spec.rb
@@ -190,7 +190,7 @@
           client = described_class.new('abc', 'def', :site => 'https://api.example.com', :auth_scheme => :request_body) do |builder|
             builder.adapter :test do |stub|
               stub.post('/oauth/token') do |env|
-                expect(env.request_headers).to include({'CustomHeader' => 'CustomHeader'})
+                expect(env.request_headers).to include('CustomHeader' => 'CustomHeader')
                 [200, {'Content-Type' => 'application/json'}, '{"access_token":"token"}']
               end
             end
@@ -205,7 +205,7 @@
           client = described_class.new('abc', 'def', :site => 'https://api.example.com', :auth_scheme => :request_body) do |builder|
             builder.adapter :test do |stub|
               stub.post('/oauth/token') do |env|
-                expect(env.request_headers).to include({'CustomHeader' => 'CustomHeader'})
+                expect(env.request_headers).to include('CustomHeader' => 'CustomHeader')
                 [200, {'Content-Type' => 'application/json'}, '{"access_token":"token"}']
               end
             end
@@ -220,7 +220,7 @@
           client = described_class.new('abc', 'def', :site => 'https://api.example.com') do |builder|
             builder.adapter :test do |stub|
               stub.post('/oauth/token') do |env|
-                expect(env.request_headers).to include({'CustomHeader' => 'CustomHeader'})
+                expect(env.request_headers).to include('CustomHeader' => 'CustomHeader')
                 [200, {'Content-Type' => 'application/json'}, '{"access_token":"token"}']
               end
             end
@@ -235,7 +235,7 @@
           client = described_class.new('abc', 'def', :site => 'https://api.example.com') do |builder|
             builder.adapter :test do |stub|
               stub.post('/oauth/token') do |env|
-                expect(env.request_headers).to include({'CustomHeader' => 'CustomHeader'})
+                expect(env.request_headers).to include('CustomHeader' => 'CustomHeader')
                 [200, {'Content-Type' => 'application/json'}, '{"access_token":"token"}']
               end
             end
@@ -299,8 +299,6 @@
         expect { subject.request(:get, error_path) }.to raise_error(OAuth2::Error)
       end
     end
-
-    # rubocop:disable Style/RedundantBegin
     it 're-encodes response body in the error message' do
       begin
         subject.request(:get, '/ascii_8bit_encoding')

From c7625596925f7e880499a74a75a4dc80f7f4eca5 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Tue, 3 May 2022 08:13:43 +0700
Subject: [PATCH 130/163] =?UTF-8?q?=F0=9F=90=9B=20rubocop=20doesn't=20supp?=
 =?UTF-8?q?ort=20-=20P=20yet?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 .github/workflows/style.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/style.yml b/.github/workflows/style.yml
index 5c4c219d..ace18f9c 100644
--- a/.github/workflows/style.yml
+++ b/.github/workflows/style.yml
@@ -40,4 +40,4 @@ jobs:
           bundler: ${{ matrix.bundler }}
           bundler-cache: true
       - name: Run Rubocop
-        run: bundle exec rubocop -DESP
+        run: bundle exec rubocop -DES

From 4a61eb014424721697408024ec6c9524404af675 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Mon, 23 May 2022 19:12:56 +0700
Subject: [PATCH 131/163] =?UTF-8?q?=F0=9F=93=8C=20Use=20rubocop-lts=20to?=
 =?UTF-8?q?=20pin=20rubocop=20@=20Ruby=201.9=20compat?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 Gemfile        | 1 -
 oauth2.gemspec | 1 +
 2 files changed, 1 insertion(+), 1 deletion(-)

diff --git a/Gemfile b/Gemfile
index 924fbfc3..dfade746 100644
--- a/Gemfile
+++ b/Gemfile
@@ -18,7 +18,6 @@ group :test do
     coverage = minimum_version.call('2.7')
     debug = minimum_version.call('2.5')
     if linting
-      gem 'rubocop-ruby1_9', '~> 1.0', :require => false
       gem 'rubocop-rspec', '1.5.0', :require => false
       gem 'rubocop-thread_safety', '0.3.1', :require => false
     end
diff --git a/oauth2.gemspec b/oauth2.gemspec
index 003b56d5..498dc565 100644
--- a/oauth2.gemspec
+++ b/oauth2.gemspec
@@ -46,5 +46,6 @@ Gem::Specification.new do |spec|
   spec.add_development_dependency 'rspec-block_is_expected'
   spec.add_development_dependency 'rspec-pending_for'
   spec.add_development_dependency 'rspec-stubbed_env'
+  spec.add_development_dependency 'rubocop-lts', ['>= 2.0.3', '~>2.0']
   spec.add_development_dependency 'silent_stream'
 end

From cc1469109f2083913cd2fd6b7ae2a8f49ea48f7a Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Mon, 23 May 2022 19:19:38 +0700
Subject: [PATCH 132/163] =?UTF-8?q?=F0=9F=93=8C=20Use=20default=20rubocop-?=
 =?UTF-8?q?lts=20rubocop=20rules?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 .rubocop.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.rubocop.yml b/.rubocop.yml
index c520c40e..d83a5c0a 100644
--- a/.rubocop.yml
+++ b/.rubocop.yml
@@ -1,5 +1,5 @@
 inherit_gem:
-  rubocop-ruby1_9: rubocop.yml
+  rubocop-lts: rubocop-lts.yml
 
 require:
   - 'rubocop-rspec'

From 984bffea03a07985f8e29a08b29b60c929d501f7 Mon Sep 17 00:00:00 2001
From: "Aleksandar N. Kostadinov" <akostadinov@gmail.com>
Date: Wed, 8 Jun 2022 08:27:06 +0300
Subject: [PATCH 133/163] use a FIPS compatible digest (#587)

---
 lib/oauth2/mac_token.rb | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/oauth2/mac_token.rb b/lib/oauth2/mac_token.rb
index 69c5ade2..3d82d0f0 100644
--- a/lib/oauth2/mac_token.rb
+++ b/lib/oauth2/mac_token.rb
@@ -62,7 +62,7 @@ def headers
     # @param [String] url the HTTP URL path of the request
     def header(verb, url)
       timestamp = Time.now.utc.to_i
-      nonce = Digest::MD5.hexdigest([timestamp, SecureRandom.hex].join(':'))
+      nonce = Digest::SHA256.hexdigest([timestamp, SecureRandom.hex].join(':'))
 
       uri = URI.parse(url)
 

From 765b03d6e40825ab989b26700f446b65fe4bfcca Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Sat, 11 Jun 2022 00:21:43 +0700
Subject: [PATCH 134/163] =?UTF-8?q?=F0=9F=94=A5=20test=5Ffiles=20is=20depr?=
 =?UTF-8?q?ecated?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 oauth2.gemspec | 1 -
 1 file changed, 1 deletion(-)

diff --git a/oauth2.gemspec b/oauth2.gemspec
index 498dc565..556bc130 100644
--- a/oauth2.gemspec
+++ b/oauth2.gemspec
@@ -35,7 +35,6 @@ Gem::Specification.new do |spec|
   spec.require_paths = %w[lib]
   spec.bindir        = 'exe'
   spec.files = Dir['lib/**/*', 'LICENSE', 'README.md', 'CHANGELOG.md', 'CODE_OF_CONDUCT.md']
-  spec.test_files = Dir['spec/**/*']
   spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
 
   spec.add_development_dependency 'addressable', '~> 2.3'

From 80fe1ce517da81dcdf1797b662cf20c5dc633299 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Tue, 28 Jun 2022 08:20:52 +0700
Subject: [PATCH 135/163] =?UTF-8?q?=F0=9F=93=A6=EF=B8=8F=20Add=20SECURITY?=
 =?UTF-8?q?=20and=20CONTRIBUTING?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 oauth2.gemspec | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/oauth2.gemspec b/oauth2.gemspec
index 556bc130..cc4e93df 100644
--- a/oauth2.gemspec
+++ b/oauth2.gemspec
@@ -34,7 +34,7 @@ Gem::Specification.new do |spec|
 
   spec.require_paths = %w[lib]
   spec.bindir        = 'exe'
-  spec.files = Dir['lib/**/*', 'LICENSE', 'README.md', 'CHANGELOG.md', 'CODE_OF_CONDUCT.md']
+  spec.files = Dir['lib/**/*', 'LICENSE', 'README.md', 'CHANGELOG.md', 'CODE_OF_CONDUCT.md', 'CONTRIBUTING.md', 'SECURITY.md']
   spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
 
   spec.add_development_dependency 'addressable', '~> 2.3'

From 00e86e45ab92d2768e4f328e9d2cc17c2020d8d3 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Tue, 28 Jun 2022 08:22:07 +0700
Subject: [PATCH 136/163] =?UTF-8?q?=F0=9F=93=9D=20Document=20v2=20release?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 README.md | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/README.md b/README.md
index b85699d9..ed15e181 100644
--- a/README.md
+++ b/README.md
@@ -16,7 +16,7 @@ This is a RubyGem for implementing OAuth 2.0 clients and servers in Ruby applica
 See the sibling `oauth` gem for OAuth 1.0 implementations in Ruby.
 
 ⚠️ **_WARNING_**: You are viewing the `README` of the soon-to-be-deprecated `1-4-stable`
-branch which for version 1.4.x releases. Version 2.0 is coming! ⚠️
+branch which for version 1.4.x releases. Please upgrade to version 2! ⚠️
 
 ---
 
@@ -258,11 +258,11 @@ of a major release, support for that Ruby version may be dropped.
 
 |     | Ruby OAuth 2 Version | Maintenance Branch | Supported Officially    | Supported Unofficially | Supported Incidentally |
 |:----|----------------------|--------------------|-------------------------|------------------------|------------------------|
-| 1️⃣ | 2.0.x (unreleased)   | `master`           | 2.7, 3.0, 3.1           | 2.5, 2.6               | 2.2, 2.3, 2.4          |
+| 1️⃣ | 2.0.x                | `master`           | 2.7, 3.0, 3.1           | 2.5, 2.6               | 2.2, 2.3, 2.4          |
 | 2️⃣ | 1.4.x                | `1-4-stable`       | 2.5, 2.6, 2.7, 3.0, 3.1 | 2.1, 2.2, 2.3, 2.4     | 1.9, 2.0               |
 | 3️⃣ | older                | N/A                | Best of luck to you!    | Please upgrade!        |                        |
 
-NOTE: Once 2.0 is released, the 1.4 series will only receive critical bug and security updates.
+NOTE: The 1.4 series will only receive critical bug and security updates.
 See [SECURITY.md][🚎sec-pol]
 
 ## Usage Examples

From 1d377640469f70d96d4161592dd57d86a15d0285 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Tue, 28 Jun 2022 08:22:25 +0700
Subject: [PATCH 137/163] =?UTF-8?q?=F0=9F=94=96=20Prepare=20release=201.4.?=
 =?UTF-8?q?10?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 CHANGELOG.md | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 988fe754..1b845bc3 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,9 +3,14 @@ All notable changes to this project will be documented in this file.
 
 ## unreleased
 
+
+## [1.4.10] - 2022-06-28
+
+- FIPS Compatibility [#587](https://github.com/oauth-xx/oauth2/pull/587) (@akostadinov)
+
 ## [1.4.9] - 2022-02-20
 
-- Fixes compatibility with Faraday v2 [572](https://github.com/oauth-xx/oauth2/issues/572)
+- Fixes compatibility with Faraday v2 [#572](https://github.com/oauth-xx/oauth2/issues/572)
 - Includes supported versions of Faraday in test matrix:
   - Faraday ~> 2.2.0 with Ruby >= 2.6
   - Faraday ~> 1.10 with Ruby >= 2.4
@@ -194,4 +199,5 @@ All notable changes to this project will be documented in this file.
 [1.4.7]: https://github.com/oauth-xx/oauth2/compare/v1.4.6...v1.4.7
 [1.4.8]: https://github.com/oauth-xx/oauth2/compare/v1.4.7...v1.4.8
 [1.4.9]: https://github.com/oauth-xx/oauth2/compare/v1.4.8...v1.4.9
-[unreleased]: https://github.com/oauth-xx/oauth2/compare/v1.4.1...HEAD
+[1.4.10]: https://github.com/oauth-xx/oauth2/compare/v1.4.9...v1.4.10
+[unreleased]: https://github.com/oauth-xx/oauth2/compare/v1.4.10...HEAD

From 9c1a595e494691c59c959cc6d5bc7ad892740aa0 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Tue, 28 Jun 2022 08:53:44 +0700
Subject: [PATCH 138/163] =?UTF-8?q?=F0=9F=94=96=20Warn=20EOL,=20and=20anno?=
 =?UTF-8?q?unce=20v2=20release=20in=20post=5Finstall=5Fmessage?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 oauth2.gemspec | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/oauth2.gemspec b/oauth2.gemspec
index cc4e93df..4c8b5f74 100644
--- a/oauth2.gemspec
+++ b/oauth2.gemspec
@@ -19,9 +19,21 @@ Gem::Specification.new do |spec|
   spec.licenses      = %w[MIT]
   spec.name          = 'oauth2'
   spec.required_ruby_version = '>= 1.9.0'
-  spec.required_rubygems_version = '>= 1.3.5'
   spec.summary       = 'A Ruby wrapper for the OAuth 2.0 protocol.'
   spec.version       = OAuth2::Version.to_s
+  spec.post_install_message = %q{
+You have installed oauth2 version 1.4.x, which is EOL.
+No further support is anticipated for the 1.4.x series.
+
+OAuth2 version 2 is released, and there are BREAKING changes!
+
+Please see:
+• https://github.com/oauth-xx/oauth2#what-is-new-for-v20
+• https://github.com/oauth-xx/oauth2/blob/master/CHANGELOG.md
+
+Please upgrade, report issues, and support the project! Thanks, |7eter l-|. l3oling
+
+}
 
   spec.metadata = {
     'bug_tracker_uri' => 'https://github.com/oauth-xx/oauth2/issues',
@@ -29,6 +41,7 @@ Gem::Specification.new do |spec|
     'documentation_uri' => "https://www.rubydoc.info/gems/oauth2/#{spec.version}",
     'source_code_uri' => "https://github.com/oauth-xx/oauth2/tree/v#{spec.version}",
     'wiki_uri' => 'https://github.com/oauth-xx/oauth2/wiki',
+    'funding_uri' => 'https://github.com/sponsors/pboling',
     'rubygems_mfa_required' => 'true',
   }
 

From b34feea24003ef1b71c51f6cb7677610a0521890 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Tue, 28 Jun 2022 08:56:05 +0700
Subject: [PATCH 139/163] =?UTF-8?q?=F0=9F=94=96=20Prepare=201.4.10?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 lib/oauth2/version.rb | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/oauth2/version.rb b/lib/oauth2/version.rb
index 88cf98dc..7b1e7c9f 100644
--- a/lib/oauth2/version.rb
+++ b/lib/oauth2/version.rb
@@ -24,7 +24,7 @@ def minor
     #
     # @return [Integer]
     def patch
-      9
+      10
     end
 
     # The pre-release version, if any

From 82f4bf44a2270d5a70217acea1fcdccaacee7d36 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Tue, 28 Jun 2022 08:57:48 +0700
Subject: [PATCH 140/163] =?UTF-8?q?=F0=9F=9A=A8=20RuboCop=20drubbing?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 oauth2.gemspec | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/oauth2.gemspec b/oauth2.gemspec
index 4c8b5f74..d3af4b32 100644
--- a/oauth2.gemspec
+++ b/oauth2.gemspec
@@ -21,7 +21,7 @@ Gem::Specification.new do |spec|
   spec.required_ruby_version = '>= 1.9.0'
   spec.summary       = 'A Ruby wrapper for the OAuth 2.0 protocol.'
   spec.version       = OAuth2::Version.to_s
-  spec.post_install_message = %q{
+  spec.post_install_message = '
 You have installed oauth2 version 1.4.x, which is EOL.
 No further support is anticipated for the 1.4.x series.
 
@@ -33,7 +33,7 @@ Please see:
 
 Please upgrade, report issues, and support the project! Thanks, |7eter l-|. l3oling
 
-}
+'
 
   spec.metadata = {
     'bug_tracker_uri' => 'https://github.com/oauth-xx/oauth2/issues',

From 795a40e5156b008c0b9a2905889d670a3549ce19 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Tue, 28 Jun 2022 09:17:11 +0700
Subject: [PATCH 141/163] =?UTF-8?q?=F0=9F=94=92=EF=B8=8F=20Clarify=20level?=
 =?UTF-8?q?=20of=20support=20for=201.4.x?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 README.md      | 24 ++++++++++++++++++------
 SECURITY.md    | 21 +++++++++++++--------
 oauth2.gemspec |  9 +++++----
 3 files changed, 36 insertions(+), 18 deletions(-)

diff --git a/README.md b/README.md
index ed15e181..695261ea 100644
--- a/README.md
+++ b/README.md
@@ -221,6 +221,18 @@ And then execute in a shell:
 bundle
 ```
 
+## OAuth2 for Enterprise
+
+Available as part of the Tidelift Subscription.
+
+The maintainers of OAuth2 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.](https://tidelift.com/subscription/pkg/rubygems-oauth2?utm_source=rubygems-oauth2&utm_medium=referral&utm_campaign=enterprise)
+
+## Security contact information
+
+To report a security vulnerability, please use the [Tidelift security contact](https://tidelift.com/security).
+Tidelift will coordinate the fix and disclosure.
+
+For more see [SECURITY.md][🚎sec-pol].
 
 ## Compatibility
 
@@ -256,13 +268,13 @@ fashion. If critical issues for a particular implementation exist at the time
 of a major release, support for that Ruby version may be dropped.
 </details>
 
-|     | Ruby OAuth 2 Version | Maintenance Branch | Supported Officially    | Supported Unofficially | Supported Incidentally |
-|:----|----------------------|--------------------|-------------------------|------------------------|------------------------|
-| 1️⃣ | 2.0.x                | `master`           | 2.7, 3.0, 3.1           | 2.5, 2.6               | 2.2, 2.3, 2.4          |
-| 2️⃣ | 1.4.x                | `1-4-stable`       | 2.5, 2.6, 2.7, 3.0, 3.1 | 2.1, 2.2, 2.3, 2.4     | 1.9, 2.0               |
-| 3️⃣ | older                | N/A                | Best of luck to you!    | Please upgrade!        |                        |
+|     | Ruby OAuth2 Version | Maintenance Branch | Supported Officially    | Supported Unofficially | Supported Incidentally |
+|:----|---------------------|--------------------|-------------------------|------------------------|------------------------|
+| 1️⃣ | 2.0.x               | `master`           | 2.7, 3.0, 3.1           | 2.5, 2.6               | 2.2, 2.3, 2.4          |
+| 2️⃣ | 1.4.x               | `1-4-stable`       | 2.5, 2.6, 2.7, 3.0, 3.1 | 2.1, 2.2, 2.3, 2.4     | 1.9, 2.0               |
+| 3️⃣ | older               | N/A                | Best of luck to you!    | Please upgrade!        |                        |
 
-NOTE: The 1.4 series will only receive critical bug and security updates.
+NOTE: The 1.4 series will only receive critical security updates.
 See [SECURITY.md][🚎sec-pol]
 
 ## Usage Examples
diff --git a/SECURITY.md b/SECURITY.md
index 9e7d133b..23405e6a 100644
--- a/SECURITY.md
+++ b/SECURITY.md
@@ -2,14 +2,19 @@
 
 ## Supported Versions
 
-| Version      | Supported |
-|--------------|-----------|
-| 2.0.<latest> | ✅         |
-| 1.4.<latest> | ✅         |
-| older        | ⛔️        |
+| Version  | Supported                          |
+|----------|------------------------------------|
+| 2.latest | ✅                                  |
+| 1.latest | ✅ (critical security updates only) |
+| older    | ⛔️                                 |
 
 ## Reporting a Vulnerability
 
-Peter Boling is the primary maintainer of this gem. Please find a way
-to [contact him directly](https://railsbling.com/contact) to report the issue. Include as much relevant information as
-possible.
+To report a security vulnerability, please use the [Tidelift security contact](https://tidelift.com/security).
+Tidelift will coordinate the fix and disclosure.
+
+## OAuth2 for Enterprise
+
+Available as part of the Tidelift Subscription.
+
+The maintainers of oauth2 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.](https://tidelift.com/subscription/pkg/rubygems-oauth2?utm_source=rubygems-oauth2&utm_medium=referral&utm_campaign=enterprise&utm_term=repo)
diff --git a/oauth2.gemspec b/oauth2.gemspec
index d3af4b32..e64bcf26 100644
--- a/oauth2.gemspec
+++ b/oauth2.gemspec
@@ -21,11 +21,12 @@ Gem::Specification.new do |spec|
   spec.required_ruby_version = '>= 1.9.0'
   spec.summary       = 'A Ruby wrapper for the OAuth 2.0 protocol.'
   spec.version       = OAuth2::Version.to_s
-  spec.post_install_message = '
-You have installed oauth2 version 1.4.x, which is EOL.
+  spec.post_install_message = "
+You have installed oauth2 version #{OAuth2::Version}, which is EOL.
 No further support is anticipated for the 1.4.x series.
 
-OAuth2 version 2 is released, and there are BREAKING changes!
+OAuth2 version 2 is released.
+There are BREAKING changes, but most will not encounter them, and upgrading should be easy!
 
 Please see:
 • https://github.com/oauth-xx/oauth2#what-is-new-for-v20
@@ -33,7 +34,7 @@ Please see:
 
 Please upgrade, report issues, and support the project! Thanks, |7eter l-|. l3oling
 
-'
+"
 
   spec.metadata = {
     'bug_tracker_uri' => 'https://github.com/oauth-xx/oauth2/issues',

From fbc83dda2670e0714913c30800fbbb4ec18ee9ef Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Tue, 28 Jun 2022 09:19:20 +0700
Subject: [PATCH 142/163] =?UTF-8?q?=F0=9F=93=9D=20Consistent=20author=20or?=
 =?UTF-8?q?der=20(most-to-least=20recent)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 oauth2.gemspec | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/oauth2.gemspec b/oauth2.gemspec
index e64bcf26..f1ecf3ac 100644
--- a/oauth2.gemspec
+++ b/oauth2.gemspec
@@ -12,7 +12,7 @@ Gem::Specification.new do |spec|
   spec.add_dependency 'multi_xml', '~> 0.5'
   spec.add_dependency 'rack', ['>= 1.2', '< 3']
 
-  spec.authors       = ['Peter Boling', 'Michael Bleigh', 'Erik Michaels-Ober']
+  spec.authors       = ['Peter Boling', 'Erik Michaels-Ober', 'Michael Bleigh']
   spec.description   = 'A Ruby wrapper for the OAuth 2.0 protocol built with a similar style to the original OAuth spec.'
   spec.email         = ['peter.boling@gmail.com']
   spec.homepage      = 'https://github.com/oauth-xx/oauth2'

From 06cf60c1931992539db0bd4e175a03cac323cb4e Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Fri, 1 Jul 2022 22:36:06 +0700
Subject: [PATCH 143/163] =?UTF-8?q?=F0=9F=93=9D=20EOL?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 README.md | 45 +++++++++++++++++++++++++++------------------
 1 file changed, 27 insertions(+), 18 deletions(-)

diff --git a/README.md b/README.md
index 695261ea..7c0cfe82 100644
--- a/README.md
+++ b/README.md
@@ -15,8 +15,13 @@ OAuth 2.0 focuses on client developer simplicity while providing specific author
 This is a RubyGem for implementing OAuth 2.0 clients and servers in Ruby applications.
 See the sibling `oauth` gem for OAuth 1.0 implementations in Ruby.
 
-⚠️ **_WARNING_**: You are viewing the `README` of the soon-to-be-deprecated `1-4-stable`
-branch which for version 1.4.x releases. Please upgrade to version 2! ⚠️
+⚠️⚠️⚠️ **_WARNING_**: You are viewing the `README` of the 
+[supported-only-for-critical-enterprise-security-issues](#oauth2-for-enterprise) `1-4-stable`
+branch. Please do not use this, and instead upgrade to version 2! ⚠️⚠️⚠️
+
+No further releases of 1.x series are planned!  [Version 2](https://github.com/oauth-xx/oauth2#what-is-new-for-v20) has *tons* of improvements!
+
+If you must continue using 1.4.x please consider purchasing an open source security maintenance contract from [Tidelift][tidelift-ref].
 
 ---
 
@@ -36,18 +41,19 @@ branch which for version 1.4.x releases. Please upgrade to version 2! ⚠️
 <details>
   <summary>1.4.x Readmes</summary>
 
-| Version | Release Date | Readme                                                   |
-|---------|--------------|----------------------------------------------------------|
-| 1.4.9   | Feb 20, 2022 | https://github.com/oauth-xx/oauth2/blob/v1.4.9/README.md |
-| 1.4.8   | Feb 18, 2022 | https://github.com/oauth-xx/oauth2/blob/v1.4.8/README.md |
-| 1.4.7   | Mar 19, 2021 | https://github.com/oauth-xx/oauth2/blob/v1.4.7/README.md |
-| 1.4.6   | Mar 19, 2021 | https://github.com/oauth-xx/oauth2/blob/v1.4.6/README.md |
-| 1.4.5   | Mar 18, 2021 | https://github.com/oauth-xx/oauth2/blob/v1.4.5/README.md |
-| 1.4.4   | Feb 12, 2020 | https://github.com/oauth-xx/oauth2/blob/v1.4.4/README.md |
-| 1.4.3   | Jan 29, 2020 | https://github.com/oauth-xx/oauth2/blob/v1.4.3/README.md |
-| 1.4.2   | Oct 1, 2019  | https://github.com/oauth-xx/oauth2/blob/v1.4.2/README.md |
-| 1.4.1   | Oct 13, 2018 | https://github.com/oauth-xx/oauth2/blob/v1.4.1/README.md |
-| 1.4.0   | Jun 9, 2017  | https://github.com/oauth-xx/oauth2/blob/v1.4.0/README.md |
+| Version | Release Date | Readme                                                    |
+|---------|--------------|-----------------------------------------------------------|
+| 1.4.10  | Jul 1, 2022  | https://github.com/oauth-xx/oauth2/blob/v1.4.10/README.md |
+| 1.4.9   | Feb 20, 2022 | https://github.com/oauth-xx/oauth2/blob/v1.4.9/README.md  |
+| 1.4.8   | Feb 18, 2022 | https://github.com/oauth-xx/oauth2/blob/v1.4.8/README.md  |
+| 1.4.7   | Mar 19, 2021 | https://github.com/oauth-xx/oauth2/blob/v1.4.7/README.md  |
+| 1.4.6   | Mar 19, 2021 | https://github.com/oauth-xx/oauth2/blob/v1.4.6/README.md  |
+| 1.4.5   | Mar 18, 2021 | https://github.com/oauth-xx/oauth2/blob/v1.4.5/README.md  |
+| 1.4.4   | Feb 12, 2020 | https://github.com/oauth-xx/oauth2/blob/v1.4.4/README.md  |
+| 1.4.3   | Jan 29, 2020 | https://github.com/oauth-xx/oauth2/blob/v1.4.3/README.md  |
+| 1.4.2   | Oct 1, 2019  | https://github.com/oauth-xx/oauth2/blob/v1.4.2/README.md  |
+| 1.4.1   | Oct 13, 2018 | https://github.com/oauth-xx/oauth2/blob/v1.4.1/README.md  |
+| 1.4.0   | Jun 9, 2017  | https://github.com/oauth-xx/oauth2/blob/v1.4.0/README.md  |
 </details>
 
 <details>
@@ -225,7 +231,9 @@ bundle
 
 Available as part of the Tidelift Subscription.
 
-The maintainers of OAuth2 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.](https://tidelift.com/subscription/pkg/rubygems-oauth2?utm_source=rubygems-oauth2&utm_medium=referral&utm_campaign=enterprise)
+The maintainers of OAuth2 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]
+
+[tidelift-ref]: https://tidelift.com/subscription/pkg/rubygems-oauth2?utm_source=rubygems-oauth2&utm_medium=referral&utm_campaign=enterprise
 
 ## Security contact information
 
@@ -236,9 +244,10 @@ For more see [SECURITY.md][🚎sec-pol].
 
 ## Compatibility
 
-Targeted ruby compatibility is non-EOL versions of Ruby, currently 2.7, 3.0 and
-3.1. Compatibility is further distinguished by supported and unsupported versions of Ruby.
-Ruby is limited to 1.9+ in the gemspec for the 1.4.x series and will be 2.2+ for 2.x releases (see `master` branch).
+Targeted ruby compatibility is 2.7, 3.0 and 3.1. Compatibility is further distinguished by
+supported and unsupported versions of Ruby.
+This gem will work with Ruby versions back to 1.9, though it remains unsupported.
+Ruby is limited to 1.9+ in the gemspec for the 1.4.x series and is be 2.2+ for next major version releases (see `master` branch).
 
 <details>
   <summary>Ruby Engine Compatibility Policy</summary>

From 4d9cee3ed5ca2c615197b838197c6e807b4ecb5c Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Fri, 1 Jul 2022 22:37:56 +0700
Subject: [PATCH 144/163] =?UTF-8?q?=F0=9F=94=A5=20Remove=20outdated=20news?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 README.md | 2 --
 1 file changed, 2 deletions(-)

diff --git a/README.md b/README.md
index 7c0cfe82..b31eac5f 100644
--- a/README.md
+++ b/README.md
@@ -27,8 +27,6 @@ If you must continue using 1.4.x please consider purchasing an open source secur
 
 * [OAuth 2.0 Spec][oauth2-spec]
 * [OAuth 1.0 sibling gem][sibling-gem]
-* Help us finish release [![2.0.0 release milestone][next-milestone-pct-img]][next-milestone-pct] by submitting or reviewing PRs and issues.
-* Oauth2 gem is _always_ looking for additional maintainers. See [#307][maintainers-discussion].
 
 [oauth2-spec]: https://oauth.net/2/
 [sibling-gem]: https://github.com/oauth-xx/oauth-ruby

From 2780313d0297dee7b9abcef4ce169f056cccd683 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Fri, 1 Jul 2022 22:38:37 +0700
Subject: [PATCH 145/163] =?UTF-8?q?=F0=9F=94=A5=20Remove=20outdated=20link?=
 =?UTF-8?q?s?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 README.md | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/README.md b/README.md
index b31eac5f..a2d1f7c0 100644
--- a/README.md
+++ b/README.md
@@ -30,9 +30,6 @@ If you must continue using 1.4.x please consider purchasing an open source secur
 
 [oauth2-spec]: https://oauth.net/2/
 [sibling-gem]: https://github.com/oauth-xx/oauth-ruby
-[next-milestone-pct]: https://github.com/oauth-xx/oauth2/milestone/1
-[next-milestone-pct-img]: https://img.shields.io/github/milestones/progress-percent/oauth-xx/oauth2/1
-[maintainers-discussion]: https://github.com/oauth-xx/oauth2/issues/307
 
 ## Release Documentation
 

From 1de8c253168037bd13918154fdb8eb73ed6a5402 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Fri, 1 Jul 2022 22:39:20 +0700
Subject: [PATCH 146/163] =?UTF-8?q?=E2=9C=8F=EF=B8=8F=20Fix=20typos?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.md b/README.md
index a2d1f7c0..7a6a40ba 100644
--- a/README.md
+++ b/README.md
@@ -133,7 +133,7 @@ The link tokens in the following sections should be kept ordered by the row and
 [📗next]: https://github.com/oauth-xx/oauth2/milestone/1
 [📗next-img]: https://img.shields.io/github/milestones/progress/oauth-xx/oauth2/1?label=Next%20Version
 
-<!-- 3️⃣ maintanence & linting -->
+<!-- 3️⃣ maintenance & linting -->
 [⛳cclim-maint]: https://codeclimate.com/github/oauth-xx/oauth2/maintainability
 [⛳cclim-maint-img]: https://api.codeclimate.com/v1/badges/688c612528ff90a46955/maintainability
 [🖇triage-help]: https://www.codetriage.com/oauth-xx/oauth2

From 12ee1f160125f6d12caf53659f63c50bd1aa793d Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Fri, 1 Jul 2022 22:40:31 +0700
Subject: [PATCH 147/163] =?UTF-8?q?=F0=9F=94=96=20Prepare=20release=201.4.?=
 =?UTF-8?q?10?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 CHANGELOG.md | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1b845bc3..794bd32a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,7 +4,7 @@ All notable changes to this project will be documented in this file.
 ## unreleased
 
 
-## [1.4.10] - 2022-06-28
+## [1.4.10] - 2022-07-01
 
 - FIPS Compatibility [#587](https://github.com/oauth-xx/oauth2/pull/587) (@akostadinov)
 
@@ -20,7 +20,7 @@ All notable changes to this project will be documented in this file.
 ## [1.4.8] - 2022-02-18
 
 - MFA is now required to push new gem versions (@pboling)
-- README overhaul w/ new Ruby Verion and Engine compatibility policies (@pboling)
+- README overhaul w/ new Ruby Version and Engine compatibility policies (@pboling)
 - [#569](https://github.com/oauth-xx/oauth2/pull/569) Backport fixes ([#561](https://github.com/oauth-xx/oauth2/pull/561) by @ryogift), and add more fixes, to allow faraday 1.x and 2.x (@jrochkind)
 - Improve Code Coverage tracking (Coveralls, CodeCov, CodeClimate), and enable branch coverage (@pboling)
 - Add CodeQL, Security Policy, Funding info (@pboling)

From 1f2f56b3f864cda878d098598acd7774ef360ac8 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Fri, 1 Jul 2022 23:21:00 +0700
Subject: [PATCH 148/163] =?UTF-8?q?=F0=9F=94=A5=20Remove=20old=20link?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 README.md | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/README.md b/README.md
index 7a6a40ba..a0dc7f81 100644
--- a/README.md
+++ b/README.md
@@ -103,7 +103,7 @@ badge #s:
 | 4️⃣ | testing               | [![Open Issues][⛳iss-o-img]][⛳iss-o] [![Closed Issues][🖇iss-c-img]][🖇iss-c] [![Supported][🏘sup-wf-img]][🏘sup-wf] [![Heads][🚎heads-wf-img]][🚎heads-wf] [![Unofficial Support][🖐uns-wf-img]][🖐uns-wf] [![MacOS][🧮mac-wf-img]][🧮mac-wf] [![Windows][📗win-wf-img]][📗win-wf]      |
 | 5️⃣ | coverage & security   | [![CodeClimate][⛳cclim-cov-img]][⛳cclim-cov] [![CodeCov][🖇codecov-img]][🖇codecov] [![Coveralls][🏘coveralls-img]][🏘coveralls] [![Security Policy][🚎sec-pol-img]][🚎sec-pol] [![CodeQL][🖐codeQL-img]][🖐codeQL] [![Code Coverage][🧮cov-wf-img]][🧮cov-wf]                           |
 | 6️⃣ | resources             | [![Discussion][⛳gh-discussions-img]][⛳gh-discussions] [![Get help on Codementor][🖇codementor-img]][🖇codementor] [![Chat][🏘chat-img]][🏘chat] [![Blog][🚎blog-img]][🚎blog] [![Blog][🖐wiki-img]][🖐wiki]                                                                              |
-| 7️⃣ | spread 💖             | [![Liberapay Patrons][⛳liberapay-img]][⛳liberapay] [![Sponsor Me][🖇sponsor-img]][🖇sponsor] [![Tweet @ Peter][🏘tweet-img]][🏘tweet] [🌏][aboutme] [👼][angelme] [💻][coderme] [🌹][politicme]                                                                                          |
+| 7️⃣ | spread 💖             | [![Liberapay Patrons][⛳liberapay-img]][⛳liberapay] [![Sponsor Me][🖇sponsor-img]][🖇sponsor] [![Tweet @ Peter][🏘tweet-img]][🏘tweet] [🌏][aboutme] [👼][angelme] [💻][coderme]                                                                                        |
 
 <!--
 The link tokens in the following sections should be kept ordered by the row and badge numbering scheme
@@ -203,8 +203,6 @@ The link tokens in the following sections should be kept ordered by the row and
 [aboutme]: https://about.me/peter.boling
 [angelme]: https://angel.co/peter-boling
 [coderme]:http://coderwall.com/pboling
-[politicme]: https://nationalprogressiveparty.org
-
 
 ## Installation
 

From 5645d671972c127849847e91f0e89e5df6736c7b Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Fri, 1 Jul 2022 23:23:34 +0700
Subject: [PATCH 149/163] =?UTF-8?q?=F0=9F=93=9D=20Documentation=20parity?=
 =?UTF-8?q?=20w/=20v2?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Peter Boling <peter.boling@gmail.com>
---
 README.md | 28 ++++++++++++++++------------
 1 file changed, 16 insertions(+), 12 deletions(-)

diff --git a/README.md b/README.md
index a0dc7f81..8ab1599a 100644
--- a/README.md
+++ b/README.md
@@ -71,6 +71,8 @@ If you must continue using 1.4.x please consider purchasing an open source secur
 | < 1.0.0  | Find here    | https://github.com/oauth-xx/oauth2/tags                  |
 </details>
 
+## Status
+
 <!--
 Numbering rows and badges in each row as a visual "database" lookup,
     as the table is extremely dense, and it can be very difficult to find anything
@@ -206,19 +208,13 @@ The link tokens in the following sections should be kept ordered by the row and
 
 ## Installation
 
-```shell
-gem install oauth2
-```
+Install the gem and add to the application's Gemfile by executing:
 
-Or inside a `Gemfile`
+    $ bundle add oauth2
 
-```ruby
-gem 'oauth2'
-```
-And then execute in a shell:
-```shell
-bundle
-```
+If bundler is not being used to manage dependencies, install the gem by executing:
+
+    $ gem install oauth2
 
 ## OAuth2 for Enterprise
 
@@ -424,7 +420,15 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
 
 ## Contributing
 
-Bug reports and pull requests are welcome on GitHub at https://github.com/oauth-xx/oauth2. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
+See [CONTRIBUTING.md][contributing]
+
+[contributing]: https://github.com/oauth-xx/oauth2/blob/master/CONTRIBUTING.md
+
+## Contributors
+
+[![Contributors](https://contrib.rocks/image?repo=oauth-xx/oauth2)]("https://github.com/oauth-xx/oauth2/graphs/contributors")
+
+Made with [contributors-img](https://contrib.rocks).
 
 ## Code of Conduct
 

From 883c5c6c6cbdefc43eb83fab882a7d8fe78370ff Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Wed, 31 Aug 2022 05:10:37 +0700
Subject: [PATCH 150/163] =?UTF-8?q?=F0=9F=9A=B8=20Housekeeping?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 CHANGELOG.md       | 2 +-
 maintenance-branch | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 794bd32a..e45a6156 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,7 +1,7 @@
 # Change Log
 All notable changes to this project will be documented in this file.
 
-## unreleased
+## [unreleased]
 
 
 ## [1.4.10] - 2022-07-01
diff --git a/maintenance-branch b/maintenance-branch
index 8b25206f..88d050b1 100644
--- a/maintenance-branch
+++ b/maintenance-branch
@@ -1 +1 @@
-master
\ No newline at end of file
+main
\ No newline at end of file

From fcf5506444dd6d3b323424362fa4c0c217f4121c Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Wed, 31 Aug 2022 05:21:56 +0700
Subject: [PATCH 151/163] =?UTF-8?q?=F0=9F=93=9D=20Document=20Enterprise=20?=
 =?UTF-8?q?support?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 SECURITY.md | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/SECURITY.md b/SECURITY.md
index 23405e6a..dbcdde72 100644
--- a/SECURITY.md
+++ b/SECURITY.md
@@ -2,11 +2,11 @@
 
 ## Supported Versions
 
-| Version  | Supported                          |
-|----------|------------------------------------|
-| 2.latest | ✅                                  |
-| 1.latest | ✅ (critical security updates only) |
-| older    | ⛔️                                 |
+| Version  | Supported | EOL     | Post-EOL / Enterprise                 |
+|----------|-----------|---------|---------------------------------------|
+| 2.latest | ✅         | 04/2024 | [Tidelift Subscription][tidelift-ref] |
+| 1.latest | ✅         | 04/2023 | [Tidelift Subscription][tidelift-ref] |
+| <= 1     | ⛔         | ⛔       | ⛔                                     |
 
 ## Reporting a Vulnerability
 
@@ -17,4 +17,6 @@ Tidelift will coordinate the fix and disclosure.
 
 Available as part of the Tidelift Subscription.
 
-The maintainers of oauth2 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.](https://tidelift.com/subscription/pkg/rubygems-oauth2?utm_source=rubygems-oauth2&utm_medium=referral&utm_campaign=enterprise&utm_term=repo)
+The maintainers of oauth2 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]
+
+[tidelift-ref]: https://tidelift.com/subscription/pkg/rubygems-oauth2?utm_source=rubygems-oauth2&utm_medium=referral&utm_campaign=enterprise&utm_term=repo

From 2fd96d6687dd5e9b727bab8a7ef3c9801d9f1724 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Wed, 31 Aug 2022 05:22:49 +0700
Subject: [PATCH 152/163] =?UTF-8?q?=F0=9F=93=9D=20Document=20EOL=20Policy?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 SECURITY.md | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/SECURITY.md b/SECURITY.md
index dbcdde72..274337d2 100644
--- a/SECURITY.md
+++ b/SECURITY.md
@@ -8,6 +8,10 @@
 | 1.latest | ✅         | 04/2023 | [Tidelift Subscription][tidelift-ref] |
 | <= 1     | ⛔         | ⛔       | ⛔                                     |
 
+### EOL Policy
+
+Non-commercial support for the oldest version of Ruby (which itself is going EOL) will be dropped each year in April.
+
 ## Reporting a Vulnerability
 
 To report a security vulnerability, please use the [Tidelift security contact](https://tidelift.com/security).

From 5bc5189ab4bb06b665de995271ec7cc09116da2a Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Thu, 15 Sep 2022 05:53:41 +0700
Subject: [PATCH 153/163] =?UTF-8?q?=F0=9F=94=A7=20Complete=20migration=20f?=
 =?UTF-8?q?rom=20master=20to=20main=20branch?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .github/workflows/codeql-analysis.yml |  4 +-
 .github/workflows/coverage.yml        |  1 -
 .github/workflows/danger.yml          |  1 -
 .github/workflows/heads.yml           |  1 -
 .github/workflows/macos-ancient.yml   |  1 -
 .github/workflows/macos.yml           |  1 -
 .github/workflows/style.yml           |  1 -
 .github/workflows/supported.yml       |  1 -
 .github/workflows/unsupported.yml     |  1 -
 .github/workflows/windows.yml         |  1 -
 CHANGELOG.md                          | 40 ++++----------
 CONTRIBUTING.md                       | 28 +++++++++-
 Dangerfile                            |  2 +-
 README.md                             | 80 ++++++++++++++++++---------
 oauth2.gemspec                        |  2 +-
 15 files changed, 94 insertions(+), 71 deletions(-)

diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml
index 5832ebea..0dc599b6 100644
--- a/.github/workflows/codeql-analysis.yml
+++ b/.github/workflows/codeql-analysis.yml
@@ -13,10 +13,10 @@ name: "CodeQL"
 
 on:
   push:
-    branches: [ master, main, "*-stable" ]
+    branches: [ main, "*-stable" ]
   pull_request:
     # The branches below must be a subset of the branches above
-    branches: [ master, main, "*-stable" ]
+    branches: [ main, "*-stable" ]
   schedule:
     - cron: '35 1 * * 5'
 
diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml
index 82f42f44..8cb14169 100644
--- a/.github/workflows/coverage.yml
+++ b/.github/workflows/coverage.yml
@@ -8,7 +8,6 @@ on:
   push:
     branches:
       - 'main'
-      - 'master'
       - '*-maintenance'
       - '*-dev'
       - '*-stable'
diff --git a/.github/workflows/danger.yml b/.github/workflows/danger.yml
index ab63ab1c..b8fdb277 100644
--- a/.github/workflows/danger.yml
+++ b/.github/workflows/danger.yml
@@ -4,7 +4,6 @@ on:
   pull_request:
     branches:
       - 'main'
-      - 'master'
       - '*-stable'
 
 jobs:
diff --git a/.github/workflows/heads.yml b/.github/workflows/heads.yml
index d56fa8b9..3cf68f50 100644
--- a/.github/workflows/heads.yml
+++ b/.github/workflows/heads.yml
@@ -4,7 +4,6 @@ on:
   push:
     branches:
       - 'main'
-      - 'master'
       - '*-maintenance'
       - '*-dev'
       - '*-stable'
diff --git a/.github/workflows/macos-ancient.yml b/.github/workflows/macos-ancient.yml
index ba2ebf62..ee26cd1a 100644
--- a/.github/workflows/macos-ancient.yml
+++ b/.github/workflows/macos-ancient.yml
@@ -4,7 +4,6 @@ on:
   push:
     branches:
       - 'main'
-      - 'master'
       - '*-maintenance'
       - '*-dev'
       - '*-stable'
diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml
index 24a0e8a7..940f230c 100644
--- a/.github/workflows/macos.yml
+++ b/.github/workflows/macos.yml
@@ -4,7 +4,6 @@ on:
   push:
     branches:
       - 'main'
-      - 'master'
       - '*-maintenance'
       - '*-dev'
       - '*-stable'
diff --git a/.github/workflows/style.yml b/.github/workflows/style.yml
index ace18f9c..a489dccc 100644
--- a/.github/workflows/style.yml
+++ b/.github/workflows/style.yml
@@ -4,7 +4,6 @@ on:
   push:
     branches:
       - 'main'
-      - 'master'
       - '*-maintenance'
       - '*-dev'
       - '*-stable'
diff --git a/.github/workflows/supported.yml b/.github/workflows/supported.yml
index 493c11bc..9fe394dd 100644
--- a/.github/workflows/supported.yml
+++ b/.github/workflows/supported.yml
@@ -4,7 +4,6 @@ on:
   push:
     branches:
       - 'main'
-      - 'master'
       - '*-maintenance'
       - '*-dev'
       - '*-stable'
diff --git a/.github/workflows/unsupported.yml b/.github/workflows/unsupported.yml
index f7670f68..53bc31e6 100644
--- a/.github/workflows/unsupported.yml
+++ b/.github/workflows/unsupported.yml
@@ -4,7 +4,6 @@ on:
   push:
     branches:
       - 'main'
-      - 'master'
       - '*-maintenance'
       - '*-dev'
       - '*-stable'
diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml
index 4f97a0da..cd848566 100644
--- a/.github/workflows/windows.yml
+++ b/.github/workflows/windows.yml
@@ -4,7 +4,6 @@ on:
   push:
     branches:
       - 'main'
-      - 'master'
       - '*-maintenance'
       - '*-dev'
       - '*-stable'
diff --git a/CHANGELOG.md b/CHANGELOG.md
index e45a6156..936f3bb4 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,16 +1,13 @@
-# Change Log
+# Changelog
 All notable changes to this project will be documented in this file.
 
 ## [unreleased]
 
-
 ## [1.4.10] - 2022-07-01
-
 - FIPS Compatibility [#587](https://github.com/oauth-xx/oauth2/pull/587) (@akostadinov)
 
 ## [1.4.9] - 2022-02-20
-
-- Fixes compatibility with Faraday v2 [#572](https://github.com/oauth-xx/oauth2/issues/572)
+- Fixes compatibility with Faraday v2 [572](https://github.com/oauth-xx/oauth2/issues/572)
 - Includes supported versions of Faraday in test matrix:
   - Faraday ~> 2.2.0 with Ruby >= 2.6
   - Faraday ~> 1.10 with Ruby >= 2.4
@@ -18,7 +15,6 @@ All notable changes to this project will be documented in this file.
 - Add Windows and MacOS to test matrix
 
 ## [1.4.8] - 2022-02-18
-
 - MFA is now required to push new gem versions (@pboling)
 - README overhaul w/ new Ruby Version and Engine compatibility policies (@pboling)
 - [#569](https://github.com/oauth-xx/oauth2/pull/569) Backport fixes ([#561](https://github.com/oauth-xx/oauth2/pull/561) by @ryogift), and add more fixes, to allow faraday 1.x and 2.x (@jrochkind)
@@ -28,40 +24,33 @@ All notable changes to this project will be documented in this file.
 - [#543](https://github.com/oauth-xx/oauth2/pull/543) - Support for more modern Open SSL libraries (@pboling)
 
 ## [1.4.7] - 2021-03-19
-
 - [#541](https://github.com/oauth-xx/oauth2/pull/541) - Backport fix to expires_at handling [#533](https://github.com/oauth-xx/oauth2/pull/533) to 1-4-stable branch. (@dobon)
 
 ## [1.4.6] - 2021-03-19
-
 - [#540](https://github.com/oauth-xx/oauth2/pull/540) - Add VERSION constant (@pboling)
 - [#537](https://github.com/oauth-xx/oauth2/pull/537) - Fix crash in OAuth2::Client#get_token (@anderscarling)
-- [#538](https://github.com/oauth-xx/oauth2/pull/538) - Remove reliance on globally included OAuth2 in tests for version 1.4 (@anderscarling)
+- [#538](https://github.com/oauth-xx/oauth2/pull/538) - Remove reliance on globally included OAuth2 in tests, analogous to [#539](https://github.com/oauth-xx/oauth2/pull/539) on main branch (@anderscarling)
 
 ## [1.4.5] - 2021-03-18
-
-- [#535](https://github.com/oauth-xx/oauth2/pull/535) - Compatibility with range of supported Ruby OpenSSL versions, Rubocop updates, Github Actions (@pboling)
+- [#535](https://github.com/oauth-xx/oauth2/pull/535) - Compatibility with range of supported Ruby OpenSSL versions, Rubocop updates, Github Actions, analogous to [#536](https://github.com/oauth-xx/oauth2/pull/536) on main branch (@pboling)
 - [#518](https://github.com/oauth-xx/oauth2/pull/518) - Add extract_access_token option to OAuth2::Client (@jonspalmer)
 - [#507](https://github.com/oauth-xx/oauth2/pull/507) - Fix camel case content type, response keys (@anvox)
 - [#500](https://github.com/oauth-xx/oauth2/pull/500) - Fix YARD documentation formatting (@olleolleolle)
 
 ## [1.4.4] - 2020-02-12
-
 - [#408](https://github.com/oauth-xx/oauth2/pull/408) - Fixed expires_at for formatted time (@Lomey)
 
 ## [1.4.3] - 2020-01-29
-
 - [#483](https://github.com/oauth-xx/oauth2/pull/483) - add project metadata to gemspec (@orien)
 - [#495](https://github.com/oauth-xx/oauth2/pull/495) - support additional types of access token requests (@SteveyblamFreeagent, @thomcorley, @dgholz)
   - Adds support for private_key_jwt and tls_client_auth
 - [#433](https://github.com/oauth-xx/oauth2/pull/433) - allow field names with square brackets and numbers in params (@asm256)
 
 ## [1.4.2] - 2019-10-01
-
 - [#478](https://github.com/oauth-xx/oauth2/pull/478) - support latest version of faraday & fix build (@pboling)
-  - officially support Ruby 2.6 and truffleruby
+  - Officially support Ruby 2.6 and truffleruby
 
 ## [1.4.1] - 2018-10-13
-
 - [#417](https://github.com/oauth-xx/oauth2/pull/417) - update jwt dependency (@thewoolleyman)
 - [#419](https://github.com/oauth-xx/oauth2/pull/419) - remove rubocop dependency (temporary, added back in [#423](https://github.com/oauth-xx/oauth2/pull/423)) (@pboling)
 - [#418](https://github.com/oauth-xx/oauth2/pull/418) - update faraday dependency (@pboling)
@@ -88,19 +77,16 @@ All notable changes to this project will be documented in this file.
 [jruby-9.2]: https://www.jruby.org/2018/05/24/jruby-9-2-0-0.html
 
 ## [1.4.0] - 2017-06-09
-
 - Drop Ruby 1.8.7 support (@sferik)
 - Fix some RuboCop offenses (@sferik)
 - _Dependency_: Remove Yardstick (@sferik)
 - _Dependency_: Upgrade Faraday to 0.12 (@sferik)
 
 ## [1.3.1] - 2017-03-03
-
 - Add support for Ruby 2.4.0 (@pschambacher)
 - _Dependency_: Upgrade Faraday to Faraday 0.11 (@mcfiredrill, @rhymes, @pschambacher)
 
 ## [1.3.0] - 2016-12-28
-
 - Add support for header-based authentication to the `Client` so it can be used across the library (@bjeanes)
 - Default to header-based authentication when getting a token from an authorisation code (@maletor)
 - **Breaking**: Allow an `auth_scheme` (`:basic_auth` or `:request_body`) to be set on the client, defaulting to `:request_body` to maintain backwards compatibility (@maletor, @bjeanes)
@@ -110,32 +96,27 @@ All notable changes to this project will be documented in this file.
 - Add support for Faraday 0.10 (@rhymes)
 
 ## [1.2.0] - 2016-07-01
-
 - Properly handle encoding of error responses (so we don't blow up, for example, when Google's response includes a ∞) (@Motoshi-Nishihira)
 - Make a copy of the options hash in `AccessToken#from_hash` to avoid accidental mutations (@Linuus)
 - Use `raise` rather than `fail` to throw exceptions (@sferik)
 
 ## [1.1.0] - 2016-01-30
-
 - Various refactors (eliminating `Hash#merge!` usage in `AccessToken#refresh!`, use `yield` instead of `#call`, freezing mutable objects in constants, replacing constants with class variables) (@sferik)
 - Add support for Rack 2, and bump various other dependencies (@sferik)
 
 ## [1.0.0] - 2014-07-09
-
 ### Added
 - Add an implementation of the MAC token spec.
-
 ### Fixed
 - Fix Base64.strict_encode64 incompatibility with Ruby 1.8.7.
 
 ## [0.5.0] - 2011-07-29
-
 ### Changed
-- [breaking] `oauth_token` renamed to `oauth_bearer`.
-- [breaking] `authorize_path` Client option renamed to `authorize_url`.
-- [breaking] `access_token_path` Client option renamed to `token_url`.
-- [breaking] `access_token_method` Client option renamed to `token_method`.
-- [breaking] `web_server` renamed to `auth_code`.
+- *breaking* `oauth_token` renamed to `oauth_bearer`.
+- *breaking* `authorize_path` Client option renamed to `authorize_url`.
+- *breaking* `access_token_path` Client option renamed to `token_url`.
+- *breaking* `access_token_method` Client option renamed to `token_method`.
+- *breaking* `web_server` renamed to `auth_code`.
 
 ## [0.4.1] - 2011-04-20
 
@@ -163,7 +144,6 @@ All notable changes to this project will be documented in this file.
 
 ## [0.0.4] + [0.0.3] + [0.0.2] + [0.0.1] - 2010-04-22
 
-
 [0.0.1]: https://github.com/oauth-xx/oauth2/compare/311d9f4...v0.0.1
 [0.0.2]: https://github.com/oauth-xx/oauth2/compare/v0.0.1...v0.0.2
 [0.0.3]: https://github.com/oauth-xx/oauth2/compare/v0.0.2...v0.0.3
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 61aa667f..ed315d0c 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,4 +1,12 @@
-## Submitting a Pull Request
+## Contributing
+
+Bug reports and pull requests are welcome on GitHub at [https://github.com/oauth-xx/oauth2][source]
+. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to
+the [code of conduct][conduct].
+
+To submit a patch, please fork the project and create a patch with tests. Once you're happy with it send a pull request!
+
+## Detailed instructions on Submitting a Pull Request
 1. [Fork the repository.][fork]
 2. [Create a topic branch.][branch]
 3. Add specs for your unimplemented feature or bug fix.
@@ -16,3 +24,21 @@
 [fork]: http://help.github.com/fork-a-repo/
 [branch]: http://learn.github.com/p/branching.html
 [pr]: http://help.github.com/send-pull-requests/
+
+## Contributors
+
+[![Contributors](https://contrib.rocks/image?repo=oauth-xx/oauth2)][contributors]
+
+Made with [contributors-img][contrib-rocks].
+
+[comment]: <> (Following links are used by README, CONTRIBUTING)
+
+[conduct]: https://github.com/oauth-xx/oauth2/blob/main/CODE_OF_CONDUCT.md
+
+[contrib-rocks]: https://contrib.rocks
+
+[contributors]: https://github.com/oauth-xx/oauth2/graphs/contributors
+
+[comment]: <> (Following links are used by README, CONTRIBUTING, Homepage)
+
+[source]: https://github.com/oauth-xx/oauth2/
diff --git a/Dangerfile b/Dangerfile
index 518ea63a..2f8600bb 100644
--- a/Dangerfile
+++ b/Dangerfile
@@ -10,6 +10,6 @@ warn('PR is classed as Work in Progress') if github.pr_title.include? '[WIP]'
 # Warn when there is a big PR
 warn('Big PR') if git.lines_of_code > 500
 
-# Don't let testing shortcuts get into master by accident
+# Don't let testing shortcuts get into main by accident
 raise('fdescribe left in tests') if `grep -r fdescribe specs/ `.length > 1
 raise('fit left in tests') if `grep -r fit specs/ `.length > 1
diff --git a/README.md b/README.md
index 8ab1599a..125c954b 100644
--- a/README.md
+++ b/README.md
@@ -1,9 +1,9 @@
 <p align="center">
-    <a href="http://oauth.net/2/" target="_blank" rel="noopener noreferrer">
-      <img src="https://github.com/oauth-xx/oauth2/raw/master/docs/images/logo/oauth2-logo-124px.png?raw=true" alt="OAuth 2.0 Logo by Chris Messina, CC BY-SA 3.0">
+    <a href="http://oauth.net/2/" target="_blank" rel="noopener">
+      <img src="https://github.com/oauth-xx/oauth2/raw/main/docs/images/logo/oauth2-logo-124px.png?raw=true" alt="OAuth 2.0 Logo by Chris Messina, CC BY-SA 3.0">
     </a>
-    <a href="https://www.ruby-lang.org/" target="_blank" rel="noopener noreferrer">
-      <img width="124px" src="https://github.com/oauth-xx/oauth2/raw/master/docs/images/logo/ruby-logo-198px.svg?raw=true" alt="Yukihiro Matsumoto, Ruby Visual Identity Team, CC BY-SA 2.5">
+    <a href="https://www.ruby-lang.org/" target="_blank" rel="noopener">
+      <img width="124px" src="https://github.com/oauth-xx/oauth2/raw/main/docs/images/logo/ruby-logo-198px.svg?raw=true" alt="Yukihiro Matsumoto, Ruby Visual Identity Team, CC BY-SA 2.5">
     </a>
 </p>
 
@@ -95,17 +95,20 @@ badge #s:
 🖐
 🧮
 📗
+
+appended indicators:
+♻️ - URL needs to be updated from SASS integration. Find / Replace is insufficient.
 -->
 
-|     | Project               | oauth2                                                                                                                                                                                                                                                                                   |
-|:----|-----------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| 1️⃣ | name, license, docs   | [![RubyGems.org][⛳️name-img]][⛳️gem] [![License: MIT][🖇src-license-img]][🖇src-license] [![FOSSA][🏘fossa-img]][🏘fossa] [![RubyDoc.info][🚎yard-img]][🚎yard] [![InchCI][🖐inch-ci-img]][🚎yard]                                                                                       |
-| 2️⃣ | version & activity    | [![Gem Version][⛳️version-img]][⛳️gem] [![Total Downloads][🖇DL-total-img]][⛳️gem] [![Download Rank][🏘DL-rank-img]][⛳️gem] [![Source Code][🚎src-home-img]][🚎src-home] [![Open PRs][🖐prs-o-img]][🖐prs-o] [![Closed PRs][🧮prs-c-img]][🧮prs-c] [![Next Version][📗next-img]][📗next] |
-| 3️⃣ | maintanence & linting | [![Maintainability][⛳cclim-maint-img]][⛳cclim-maint] [![Helpers][🖇triage-help-img]][🖇triage-help] [![Depfu][🏘depfu-img]][🏘depfu] [![Contributors][🚎contributors-img]][🚎contributors] [![Style][🖐style-wf-img]][🖐style-wf] [![Kloc Roll][🧮kloc-img]][🧮kloc]                     |
-| 4️⃣ | testing               | [![Open Issues][⛳iss-o-img]][⛳iss-o] [![Closed Issues][🖇iss-c-img]][🖇iss-c] [![Supported][🏘sup-wf-img]][🏘sup-wf] [![Heads][🚎heads-wf-img]][🚎heads-wf] [![Unofficial Support][🖐uns-wf-img]][🖐uns-wf] [![MacOS][🧮mac-wf-img]][🧮mac-wf] [![Windows][📗win-wf-img]][📗win-wf]      |
-| 5️⃣ | coverage & security   | [![CodeClimate][⛳cclim-cov-img]][⛳cclim-cov] [![CodeCov][🖇codecov-img]][🖇codecov] [![Coveralls][🏘coveralls-img]][🏘coveralls] [![Security Policy][🚎sec-pol-img]][🚎sec-pol] [![CodeQL][🖐codeQL-img]][🖐codeQL] [![Code Coverage][🧮cov-wf-img]][🧮cov-wf]                           |
-| 6️⃣ | resources             | [![Discussion][⛳gh-discussions-img]][⛳gh-discussions] [![Get help on Codementor][🖇codementor-img]][🖇codementor] [![Chat][🏘chat-img]][🏘chat] [![Blog][🚎blog-img]][🚎blog] [![Blog][🖐wiki-img]][🖐wiki]                                                                              |
-| 7️⃣ | spread 💖             | [![Liberapay Patrons][⛳liberapay-img]][⛳liberapay] [![Sponsor Me][🖇sponsor-img]][🖇sponsor] [![Tweet @ Peter][🏘tweet-img]][🏘tweet] [🌏][aboutme] [👼][angelme] [💻][coderme]                                                                                        |
+|     | Project               | bundle add oauth2                                                                                                                                                                                                                                                                            |
+|:----|-----------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| 1️⃣ | name, license, docs   | [![RubyGems.org][⛳️name-img]][⛳️gem] [![License: MIT][🖇src-license-img]][🖇src-license] [![FOSSA][🏘fossa-img]][🏘fossa] [![RubyDoc.info][🚎yard-img]][🚎yard] [![InchCI][🖐inch-ci-img]][🚎yard]                                                                                           |
+| 2️⃣ | version & activity    | [![Gem Version][⛳️version-img]][⛳️gem] [![Total Downloads][🖇DL-total-img]][⛳️gem] [![Download Rank][🏘DL-rank-img]][⛳️gem] [![Source Code][🚎src-home-img]][🚎src-home] [![Open PRs][🖐prs-o-img]][🖐prs-o] [![Closed PRs][🧮prs-c-img]][🧮prs-c] [![Next Version][📗next-img♻️]][📗next♻️] |
+| 3️⃣ | maintanence & linting | [![Maintainability][⛳cclim-maint-img♻️]][⛳cclim-maint] [![Helpers][🖇triage-help-img]][🖇triage-help] [![Depfu][🏘depfu-img♻️]][🏘depfu♻️] [![Contributors][🚎contributors-img]][🚎contributors] [![Style][🖐style-wf-img]][🖐style-wf] [![Kloc Roll][🧮kloc-img]][🧮kloc]                   |
+| 4️⃣ | testing               | [![Open Issues][⛳iss-o-img]][⛳iss-o] [![Closed Issues][🖇iss-c-img]][🖇iss-c] [![Supported][🏘sup-wf-img]][🏘sup-wf] [![Heads][🚎heads-wf-img]][🚎heads-wf] [![Unofficial Support][🖐uns-wf-img]][🖐uns-wf] [![MacOS][🧮mac-wf-img]][🧮mac-wf] [![Windows][📗win-wf-img]][📗win-wf]          |
+| 5️⃣ | coverage & security   | [![CodeClimate][⛳cclim-cov-img♻️]][⛳cclim-cov] [![CodeCov][🖇codecov-img♻️]][🖇codecov] [![Coveralls][🏘coveralls-img]][🏘coveralls] [![Security Policy][🚎sec-pol-img]][🚎sec-pol] [![CodeQL][🖐codeQL-img]][🖐codeQL] [![Code Coverage][🧮cov-wf-img]][🧮cov-wf]                           |
+| 6️⃣ | resources             | [![Discussion][⛳gh-discussions-img]][⛳gh-discussions] [![Get help on Codementor][🖇codementor-img]][🖇codementor] [![Chat][🏘chat-img]][🏘chat] [![Blog][🚎blog-img]][🚎blog] [![Blog][🖐wiki-img]][🖐wiki]                                                                                  |
+| 7️⃣ | spread 💖             | [![Liberapay Patrons][⛳liberapay-img]][⛳liberapay] [![Sponsor Me][🖇sponsor-img]][🖇sponsor] [![Tweet @ Peter][🏘tweet-img]][🏘tweet] [🌏][aboutme] [👼][angelme] [💻][coderme]                                                                                                              |
 
 <!--
 The link tokens in the following sections should be kept ordered by the row and badge numbering scheme
@@ -132,16 +135,16 @@ The link tokens in the following sections should be kept ordered by the row and
 [🖐prs-o-img]: https://img.shields.io/github/issues-pr/oauth-xx/oauth2
 [🧮prs-c]: https://github.com/oauth-xx/oauth2/pulls?q=is%3Apr+is%3Aclosed
 [🧮prs-c-img]: https://img.shields.io/github/issues-pr-closed/oauth-xx/oauth2
-[📗next]: https://github.com/oauth-xx/oauth2/milestone/1
-[📗next-img]: https://img.shields.io/github/milestones/progress/oauth-xx/oauth2/1?label=Next%20Version
+[📗next♻️]: https://github.com/oauth-xx/oauth2/milestone/2
+[📗next-img♻️]: https://img.shields.io/github/milestones/progress/oauth-xx/oauth2/2?label=Next%20Version
 
 <!-- 3️⃣ maintenance & linting -->
 [⛳cclim-maint]: https://codeclimate.com/github/oauth-xx/oauth2/maintainability
-[⛳cclim-maint-img]: https://api.codeclimate.com/v1/badges/688c612528ff90a46955/maintainability
+[⛳cclim-maint-img♻️]: https://api.codeclimate.com/v1/badges/688c612528ff90a46955/maintainability
 [🖇triage-help]: https://www.codetriage.com/oauth-xx/oauth2
 [🖇triage-help-img]: https://www.codetriage.com/oauth-xx/oauth2/badges/users.svg
-[🏘depfu]: https://depfu.com/github/oauth-xx/oauth2?project_id=4445
-[🏘depfu-img]: https://badges.depfu.com/badges/6d34dc1ba682bbdf9ae2a97848241743/count.svg
+[🏘depfu♻️]: https://depfu.com/github/oauth-xx/oauth2?project_id=4445
+[🏘depfu-img♻️]: https://badges.depfu.com/badges/6d34dc1ba682bbdf9ae2a97848241743/count.svg
 [🚎contributors]: https://github.com/oauth-xx/oauth2/graphs/contributors
 [🚎contributors-img]: https://img.shields.io/github/contributors-anon/oauth-xx/oauth2
 [🖐style-wf]: https://github.com/oauth-xx/oauth2/actions/workflows/style.yml
@@ -167,12 +170,12 @@ The link tokens in the following sections should be kept ordered by the row and
 
 <!-- 5️⃣ coverage & security -->
 [⛳cclim-cov]: https://codeclimate.com/github/oauth-xx/oauth2/test_coverage
-[⛳cclim-cov-img]: https://api.codeclimate.com/v1/badges/688c612528ff90a46955/test_coverage
-[🖇codecov-img]: https://codecov.io/gh/oauth-xx/oauth2/branch/1-4-stable/graph/badge.svg?token=bNqSzNiuo2
+[⛳cclim-cov-img♻️]: https://api.codeclimate.com/v1/badges/688c612528ff90a46955/test_coverage
+[🖇codecov-img♻️]: https://codecov.io/gh/oauth-xx/oauth2/branch/1-4-stable/graph/badge.svg?token=bNqSzNiuo2
 [🖇codecov]: https://codecov.io/gh/oauth-xx/oauth2
 [🏘coveralls]: https://coveralls.io/github/oauth-xx/oauth2?branch=1-4-stable
 [🏘coveralls-img]: https://coveralls.io/repos/github/oauth-xx/oauth2/badge.svg?branch=1-4-stable
-[🚎sec-pol]: https://github.com/oauth-xx/oauth2/blob/master/SECURITY.md
+[🚎sec-pol]: https://github.com/oauth-xx/oauth2/blob/main/SECURITY.md
 [🚎sec-pol-img]: https://img.shields.io/badge/security-policy-brightgreen.svg?style=flat
 [🖐codeQL]: https://github.com/oauth-xx/oauth2/security/code-scanning
 [🖐codeQL-img]: https://github.com/oauth-xx/oauth2/actions/workflows/codeql-analysis.yml/badge.svg
@@ -231,7 +234,30 @@ Tidelift will coordinate the fix and disclosure.
 
 For more see [SECURITY.md][🚎sec-pol].
 
-## Compatibility
+## Why should you upgrade to version v2.0?
+
+- Officially support Ruby versions >= 2.7
+- Unofficially support Ruby versions >= 2.5
+- Incidentally support Ruby versions >= 2.2
+- Drop support for the expired MAC Draft (all versions)
+- Support IETF rfc7523 JWT Bearer Tokens
+- Support IETF rfc7231 Relative Location in Redirect
+- Support IETF rfc6749 Don't set oauth params when nil
+- Support [OIDC 1.0 Private Key JWT](https://openid.net/specs/openid-connect-core-1_0.html#ClientAuthentication); based on the OAuth JWT assertion specification [(RFC 7523)](https://tools.ietf.org/html/rfc7523)
+- Support new formats, including from [jsonapi.org](http://jsonapi.org/format/): `application/vdn.api+json`, `application/vnd.collection+json`, `application/hal+json`, `application/problem+json`
+- Adds new option to `OAuth2::Client#get_token`:
+  - `:access_token_class` (`AccessToken`); user specified class to use for all calls to `get_token`
+- Adds new option to `OAuth2::AccessToken#initialize`:
+  - `:expires_latency` (`nil`); number of seconds by which AccessToken validity will be reduced to offset latency
+- By default, keys are transformed to camel case.
+  - Original keys will still work as previously, in most scenarios, thanks to `rash_alt` gem.
+  - However, this is a _breaking_ change if you rely on `response.parsed.to_h`, as the keys in the result will be camel case.
+  - As of version 2.0.4 you can turn key transformation off with the `snaky: false` option.
+- By default, the `:auth_scheme` is now `:basic_auth` (instead of `:request_body`)
+  - Third-party strategies and gems may need to be updated if a provider was requiring client id/secret in the request body
+- [... A lot more](https://github.com/oauth-xx/oauth2/blob/main/CHANGELOG.md#2.0.0)
+
+## Compatibility for v1.4.x series
 
 Targeted ruby compatibility is 2.7, 3.0 and 3.1. Compatibility is further distinguished by
 supported and unsupported versions of Ruby.
@@ -268,7 +294,7 @@ of a major release, support for that Ruby version may be dropped.
 
 |     | Ruby OAuth2 Version | Maintenance Branch | Supported Officially    | Supported Unofficially | Supported Incidentally |
 |:----|---------------------|--------------------|-------------------------|------------------------|------------------------|
-| 1️⃣ | 2.0.x               | `master`           | 2.7, 3.0, 3.1           | 2.5, 2.6               | 2.2, 2.3, 2.4          |
+| 1️⃣ | 2.0.x               | `main`             | 2.7, 3.0, 3.1           | 2.5, 2.6               | 2.2, 2.3, 2.4          |
 | 2️⃣ | 1.4.x               | `1-4-stable`       | 2.5, 2.6, 2.7, 3.0, 3.1 | 2.1, 2.2, 2.3, 2.4     | 1.9, 2.0               |
 | 3️⃣ | older               | N/A                | Best of luck to you!    | Please upgrade!        |                        |
 
@@ -408,13 +434,13 @@ spec.add_dependency 'oauth2', '~> 1.4'
 
 [![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Foauth-xx%2Foauth2.svg?type=large)][fossa2]
 
-[license]: https://github.com/oauth-xx/oauth2/blob/master/LICENSE
+[license]: https://github.com/oauth-xx/oauth2/blob/main/LICENSE
 [oauth-xx]: https://github.com/oauth-xx
 [fossa2]: https://app.fossa.io/projects/git%2Bgithub.com%2Foauth-xx%2Foauth2?ref=badge_large
 
 ## Development
 
-After checking out the repo, run `bundle install` to install dependencies. Then, run `bundle excec rake spec` to run the tests.
+After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
 
 To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
 
@@ -422,7 +448,7 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
 
 See [CONTRIBUTING.md][contributing]
 
-[contributing]: https://github.com/oauth-xx/oauth2/blob/master/CONTRIBUTING.md
+[contributing]: https://github.com/oauth-xx/oauth2/blob/main/CONTRIBUTING.md
 
 ## Contributors
 
@@ -432,4 +458,4 @@ Made with [contributors-img](https://contrib.rocks).
 
 ## Code of Conduct
 
-Everyone interacting in the OAuth2 project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/oauth-xx/oauth2/blob/master/CODE_OF_CONDUCT.md).
+Everyone interacting in the OAuth2 project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/oauth-xx/oauth2/blob/main/CODE_OF_CONDUCT.md).
diff --git a/oauth2.gemspec b/oauth2.gemspec
index f1ecf3ac..5e491a94 100644
--- a/oauth2.gemspec
+++ b/oauth2.gemspec
@@ -30,7 +30,7 @@ There are BREAKING changes, but most will not encounter them, and upgrading shou
 
 Please see:
 • https://github.com/oauth-xx/oauth2#what-is-new-for-v20
-• https://github.com/oauth-xx/oauth2/blob/master/CHANGELOG.md
+• https://github.com/oauth-xx/oauth2/blob/main/CHANGELOG.md
 
 Please upgrade, report issues, and support the project! Thanks, |7eter l-|. l3oling
 

From 5ae49f76ddc271b6847d7a48fdceb3b92af2536d Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Thu, 15 Sep 2022 06:54:13 +0700
Subject: [PATCH 154/163] =?UTF-8?q?=F0=9F=94=A8=20bin=20files?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 bin/bundle  | 116 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 bin/console |  16 ++++++++
 bin/rake    |  27 ++++++++++++
 bin/rspec   |  27 ++++++++++++
 bin/rubocop |  27 ++++++++++++
 bin/setup   |   8 ++++
 6 files changed, 221 insertions(+)
 create mode 100755 bin/bundle
 create mode 100755 bin/console
 create mode 100755 bin/rake
 create mode 100755 bin/rspec
 create mode 100755 bin/rubocop
 create mode 100755 bin/setup

diff --git a/bin/bundle b/bin/bundle
new file mode 100755
index 00000000..fece50fe
--- /dev/null
+++ b/bin/bundle
@@ -0,0 +1,116 @@
+#!/usr/bin/env ruby
+# frozen_string_literal: true
+
+#
+# This file was generated by Bundler.
+#
+# The application 'bundle' is installed as part of a gem, and
+# this file is here to facilitate running it.
+#
+
+require 'rubygems'
+
+m = Module.new do
+module_function
+
+  def invoked_as_script?
+    File.expand_path($PROGRAM_NAME) == File.expand_path(__FILE__)
+  end
+
+  def env_var_version
+    ENV['BUNDLER_VERSION']
+  end
+
+  def cli_arg_version
+    return unless invoked_as_script? # don't want to hijack other binstubs
+    return unless 'update'.start_with?(ARGV.first || ' ') # must be running `bundle update`
+
+    bundler_version = nil
+    update_index = nil
+    ARGV.each_with_index do |a, i|
+      bundler_version = a if update_index && update_index.succ == i && a =~ Gem::Version::ANCHORED_VERSION_PATTERN
+      next unless a =~ /\A--bundler(?:[= ](#{Gem::Version::VERSION_PATTERN}))?\z/
+
+      bundler_version = Regexp.last_match(1)
+      update_index = i
+    end
+    bundler_version
+  end
+
+  def gemfile
+    gemfile = ENV['BUNDLE_GEMFILE']
+    return gemfile if gemfile && !gemfile.empty?
+
+    File.expand_path('../Gemfile', __dir__)
+  end
+
+  def lockfile
+    lockfile =
+      case File.basename(gemfile)
+      when 'gems.rb' then gemfile.sub(/\.rb$/, gemfile)
+      else "#{gemfile}.lock"
+      end
+    File.expand_path(lockfile)
+  end
+
+  def lockfile_version
+    return unless File.file?(lockfile)
+
+    lockfile_contents = File.read(lockfile)
+    return unless lockfile_contents =~ /\n\nBUNDLED WITH\n\s{2,}(#{Gem::Version::VERSION_PATTERN})\n/
+
+    Regexp.last_match(1)
+  end
+
+  def bundler_requirement
+    @bundler_requirement ||=
+      env_var_version || cli_arg_version ||
+      bundler_requirement_for(lockfile_version)
+  end
+
+  def bundler_requirement_for(version)
+    return "#{Gem::Requirement.default}.a" unless version
+
+    bundler_gem_version = Gem::Version.new(version)
+
+    requirement = bundler_gem_version.approximate_recommendation
+
+    return requirement unless Gem.rubygems_version < Gem::Version.new('2.7.0')
+
+    requirement += '.a' if bundler_gem_version.prerelease?
+
+    requirement
+  end
+
+  def load_bundler!
+    ENV['BUNDLE_GEMFILE'] ||= gemfile
+
+    activate_bundler
+  end
+
+  def activate_bundler
+    gem_error = activation_error_handling do
+      gem 'bundler', bundler_requirement
+    end
+    return if gem_error.nil?
+
+    require_error = activation_error_handling do
+      require 'bundler/version'
+    end
+    return if require_error.nil? && Gem::Requirement.new(bundler_requirement).satisfied_by?(Gem::Version.new(Bundler::VERSION))
+
+    warn "Activating bundler (#{bundler_requirement}) failed:\n#{gem_error.message}\n\nTo install the version of bundler this project requires, run `gem install bundler -v '#{bundler_requirement}'`"
+    exit 42
+  end
+
+  def activation_error_handling
+    yield
+    nil
+  rescue StandardError, LoadError => e
+    e
+  end
+end
+
+m.load_bundler!
+
+load Gem.bin_path('bundler', 'bundle') if m.invoked_as_script?
diff --git a/bin/console b/bin/console
new file mode 100755
index 00000000..d8fb16d0
--- /dev/null
+++ b/bin/console
@@ -0,0 +1,16 @@
+#!/usr/bin/env ruby
+# frozen_string_literal: true
+
+require 'bundler/setup'
+require 'oauth2'
+
+# You can add fixtures and/or initialization code here to make experimenting
+# with your gem easier. You can also use a different console, if you like.
+require 'byebug' if ENV['DEBUG'] == 'true'
+
+# (If you use this, don't forget to add pry to your Gemfile!)
+# require "pry"
+# Pry.start
+
+require 'irb'
+IRB.start(__FILE__)
diff --git a/bin/rake b/bin/rake
new file mode 100755
index 00000000..5f615c2a
--- /dev/null
+++ b/bin/rake
@@ -0,0 +1,27 @@
+#!/usr/bin/env ruby
+# frozen_string_literal: true
+
+#
+# This file was generated by Bundler.
+#
+# The application 'rake' is installed as part of a gem, and
+# this file is here to facilitate running it.
+#
+
+ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
+
+bundle_binstub = File.expand_path('bundle', __dir__)
+
+if File.file?(bundle_binstub)
+  if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
+    load(bundle_binstub)
+  else
+    abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
+Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
+  end
+end
+
+require 'rubygems'
+require 'bundler/setup'
+
+load Gem.bin_path('rake', 'rake')
diff --git a/bin/rspec b/bin/rspec
new file mode 100755
index 00000000..d3f4959a
--- /dev/null
+++ b/bin/rspec
@@ -0,0 +1,27 @@
+#!/usr/bin/env ruby
+# frozen_string_literal: true
+
+#
+# This file was generated by Bundler.
+#
+# The application 'rspec' is installed as part of a gem, and
+# this file is here to facilitate running it.
+#
+
+ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
+
+bundle_binstub = File.expand_path('bundle', __dir__)
+
+if File.file?(bundle_binstub)
+  if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
+    load(bundle_binstub)
+  else
+    abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
+Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
+  end
+end
+
+require 'rubygems'
+require 'bundler/setup'
+
+load Gem.bin_path('rspec-core', 'rspec')
diff --git a/bin/rubocop b/bin/rubocop
new file mode 100755
index 00000000..cc105e8d
--- /dev/null
+++ b/bin/rubocop
@@ -0,0 +1,27 @@
+#!/usr/bin/env ruby
+# frozen_string_literal: true
+
+#
+# This file was generated by Bundler.
+#
+# The application 'rubocop' is installed as part of a gem, and
+# this file is here to facilitate running it.
+#
+
+ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
+
+bundle_binstub = File.expand_path('bundle', __dir__)
+
+if File.file?(bundle_binstub)
+  if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
+    load(bundle_binstub)
+  else
+    abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
+Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
+  end
+end
+
+require 'rubygems'
+require 'bundler/setup'
+
+load Gem.bin_path('rubocop', 'rubocop')
diff --git a/bin/setup b/bin/setup
new file mode 100755
index 00000000..dce67d86
--- /dev/null
+++ b/bin/setup
@@ -0,0 +1,8 @@
+#!/usr/bin/env bash
+set -euo pipefail
+IFS=$'\n\t'
+set -vx
+
+bundle install
+
+# Do any other automated setup that you need to do here

From 59e1dc1afbd5d69898ee0974f14f61cba9bfb930 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Thu, 15 Sep 2022 07:15:22 +0700
Subject: [PATCH 155/163] =?UTF-8?q?=E2=AC=86=EF=B8=8F=20Allow=20rack=20v3?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 oauth2.gemspec | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/oauth2.gemspec b/oauth2.gemspec
index 5e491a94..16dbe8d9 100644
--- a/oauth2.gemspec
+++ b/oauth2.gemspec
@@ -10,7 +10,7 @@ Gem::Specification.new do |spec|
   spec.add_dependency 'jwt', ['>= 1.0', '< 3.0']
   spec.add_dependency 'multi_json', '~> 1.3'
   spec.add_dependency 'multi_xml', '~> 0.5'
-  spec.add_dependency 'rack', ['>= 1.2', '< 3']
+  spec.add_dependency 'rack', ['>= 1.2', '< 4']
 
   spec.authors       = ['Peter Boling', 'Erik Michaels-Ober', 'Michael Bleigh']
   spec.description   = 'A Ruby wrapper for the OAuth 2.0 protocol built with a similar style to the original OAuth spec.'

From 04b2527c471b1f90af840d14234f9cbdc09f8961 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Thu, 15 Sep 2022 08:06:04 +0700
Subject: [PATCH 156/163] =?UTF-8?q?=F0=9F=94=A7=20Migration=20from=20Githu?=
 =?UTF-8?q?b=20to=20Gitlab?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 oauth2.gemspec | 48 ++++++++++++++++++++++++++++++------------------
 1 file changed, 30 insertions(+), 18 deletions(-)

diff --git a/oauth2.gemspec b/oauth2.gemspec
index 16dbe8d9..08580113 100644
--- a/oauth2.gemspec
+++ b/oauth2.gemspec
@@ -1,4 +1,4 @@
-# coding: utf-8
+# encoding: utf-8
 # frozen_string_literal: true
 
 lib = File.expand_path('../lib', __FILE__)
@@ -15,7 +15,7 @@ Gem::Specification.new do |spec|
   spec.authors       = ['Peter Boling', 'Erik Michaels-Ober', 'Michael Bleigh']
   spec.description   = 'A Ruby wrapper for the OAuth 2.0 protocol built with a similar style to the original OAuth spec.'
   spec.email         = ['peter.boling@gmail.com']
-  spec.homepage      = 'https://github.com/oauth-xx/oauth2'
+  spec.homepage      = 'https://gitlab.com/oauth-xx/oauth2'
   spec.licenses      = %w[MIT]
   spec.name          = 'oauth2'
   spec.required_ruby_version = '>= 1.9.0'
@@ -28,34 +28,46 @@ No further support is anticipated for the 1.4.x series.
 OAuth2 version 2 is released.
 There are BREAKING changes, but most will not encounter them, and upgrading should be easy!
 
+We have made two other major migrations:
+1. master branch renamed to main
+2. Github has been replaced with Gitlab
+
 Please see:
-• https://github.com/oauth-xx/oauth2#what-is-new-for-v20
-• https://github.com/oauth-xx/oauth2/blob/main/CHANGELOG.md
+• https://gitlab.com/oauth-xx/oauth2#what-is-new-for-v20
+• https://gitlab.com/oauth-xx/oauth2/-/blob/main/CHANGELOG.md
+• https://groups.google.com/g/oauth-ruby/c/QA_dtrXWXaE
 
 Please upgrade, report issues, and support the project! Thanks, |7eter l-|. l3oling
 
 "
 
-  spec.metadata = {
-    'bug_tracker_uri' => 'https://github.com/oauth-xx/oauth2/issues',
-    'changelog_uri' => "https://github.com/oauth-xx/oauth2/blob/v#{spec.version}/CHANGELOG.md",
-    'documentation_uri' => "https://www.rubydoc.info/gems/oauth2/#{spec.version}",
-    'source_code_uri' => "https://github.com/oauth-xx/oauth2/tree/v#{spec.version}",
-    'wiki_uri' => 'https://github.com/oauth-xx/oauth2/wiki',
-    'funding_uri' => 'https://github.com/sponsors/pboling',
-    'rubygems_mfa_required' => 'true',
-  }
+  spec.metadata['homepage_uri'] = spec.homepage
+  spec.metadata['source_code_uri'] = "#{spec.homepage}/-/tree/v#{spec.version}"
+  spec.metadata['changelog_uri'] = "#{spec.homepage}/-/blob/v#{spec.version}/CHANGELOG.md"
+  spec.metadata['bug_tracker_uri'] = "#{spec.homepage}/-/issues"
+  spec.metadata['documentation_uri'] = "https://www.rubydoc.info/gems/#{spec.name}/#{spec.version}"
+  spec.metadata['wiki_uri'] = "#{spec.homepage}/-/wiki"
+  spec.metadata['funding_uri'] = "https://liberapay.com/pboling"
+  spec.metadata['rubygems_mfa_required'] = 'true'
 
   spec.require_paths = %w[lib]
   spec.bindir        = 'exe'
-  spec.files = Dir['lib/**/*', 'LICENSE', 'README.md', 'CHANGELOG.md', 'CODE_OF_CONDUCT.md', 'CONTRIBUTING.md', 'SECURITY.md']
+  spec.files = Dir[
+    'lib/**/*',
+    'CHANGELOG.md',
+    'CODE_OF_CONDUCT.md',
+    'CONTRIBUTING.md',
+    'LICENSE',
+    'README.md',
+    'SECURITY.md',
+  ]
   spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
 
-  spec.add_development_dependency 'addressable', '~> 2.3'
+  spec.add_development_dependency 'addressable', '>= 2'
   spec.add_development_dependency 'bundler', '>= 1.16'
-  spec.add_development_dependency 'rake', '>= 12.3'
-  spec.add_development_dependency 'rexml', '~> 3.2'
-  spec.add_development_dependency 'rspec', '~> 3.0'
+  spec.add_development_dependency 'rake', '>= 12'
+  spec.add_development_dependency 'rexml', '>= 3'
+  spec.add_development_dependency 'rspec', '>= 3'
   spec.add_development_dependency 'rspec-block_is_expected'
   spec.add_development_dependency 'rspec-pending_for'
   spec.add_development_dependency 'rspec-stubbed_env'

From 4423b05252b2c1867b64785739af89d5bddecdb8 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Fri, 16 Sep 2022 11:42:48 +0700
Subject: [PATCH 157/163] =?UTF-8?q?=F0=9F=94=A7=20Migration=20from=20Githu?=
 =?UTF-8?q?b=20to=20Gitlab?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 CHANGELOG.md    | 122 ++++++++++++++++++++++++------------------------
 CONTRIBUTING.md |   8 ++--
 README.md       | 101 ++++++++++++++++++---------------------
 3 files changed, 110 insertions(+), 121 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 936f3bb4..d918fdf1 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,10 +4,10 @@ All notable changes to this project will be documented in this file.
 ## [unreleased]
 
 ## [1.4.10] - 2022-07-01
-- FIPS Compatibility [#587](https://github.com/oauth-xx/oauth2/pull/587) (@akostadinov)
+- FIPS Compatibility [#587](https://gitlab.com/oauth-xx/oauth2/-/merge_requests/587) (@akostadinov)
 
 ## [1.4.9] - 2022-02-20
-- Fixes compatibility with Faraday v2 [572](https://github.com/oauth-xx/oauth2/issues/572)
+- Fixes compatibility with Faraday v2 [572](https://gitlab.com/oauth-xx/oauth2/-/issues/572)
 - Includes supported versions of Faraday in test matrix:
   - Faraday ~> 2.2.0 with Ruby >= 2.6
   - Faraday ~> 1.10 with Ruby >= 2.4
@@ -17,47 +17,47 @@ All notable changes to this project will be documented in this file.
 ## [1.4.8] - 2022-02-18
 - MFA is now required to push new gem versions (@pboling)
 - README overhaul w/ new Ruby Version and Engine compatibility policies (@pboling)
-- [#569](https://github.com/oauth-xx/oauth2/pull/569) Backport fixes ([#561](https://github.com/oauth-xx/oauth2/pull/561) by @ryogift), and add more fixes, to allow faraday 1.x and 2.x (@jrochkind)
+- [#569](https://gitlab.com/oauth-xx/oauth2/-/merge_requests/569) Backport fixes ([#561](https://gitlab.com/oauth-xx/oauth2/-/merge_requests/561) by @ryogift), and add more fixes, to allow faraday 1.x and 2.x (@jrochkind)
 - Improve Code Coverage tracking (Coveralls, CodeCov, CodeClimate), and enable branch coverage (@pboling)
 - Add CodeQL, Security Policy, Funding info (@pboling)
 - Added Ruby 3.1, jruby, jruby-head, truffleruby, truffleruby-head to build matrix (@pboling)
-- [#543](https://github.com/oauth-xx/oauth2/pull/543) - Support for more modern Open SSL libraries (@pboling)
+- [#543](https://gitlab.com/oauth-xx/oauth2/-/merge_requests/543) - Support for more modern Open SSL libraries (@pboling)
 
 ## [1.4.7] - 2021-03-19
-- [#541](https://github.com/oauth-xx/oauth2/pull/541) - Backport fix to expires_at handling [#533](https://github.com/oauth-xx/oauth2/pull/533) to 1-4-stable branch. (@dobon)
+- [#541](https://gitlab.com/oauth-xx/oauth2/-/merge_requests/541) - Backport fix to expires_at handling [#533](https://gitlab.com/oauth-xx/oauth2/-/merge_requests/533) to 1-4-stable branch. (@dobon)
 
 ## [1.4.6] - 2021-03-19
-- [#540](https://github.com/oauth-xx/oauth2/pull/540) - Add VERSION constant (@pboling)
-- [#537](https://github.com/oauth-xx/oauth2/pull/537) - Fix crash in OAuth2::Client#get_token (@anderscarling)
-- [#538](https://github.com/oauth-xx/oauth2/pull/538) - Remove reliance on globally included OAuth2 in tests, analogous to [#539](https://github.com/oauth-xx/oauth2/pull/539) on main branch (@anderscarling)
+- [#540](https://gitlab.com/oauth-xx/oauth2/-/merge_requests/540) - Add VERSION constant (@pboling)
+- [#537](https://gitlab.com/oauth-xx/oauth2/-/merge_requests/537) - Fix crash in OAuth2::Client#get_token (@anderscarling)
+- [#538](https://gitlab.com/oauth-xx/oauth2/-/merge_requests/538) - Remove reliance on globally included OAuth2 in tests, analogous to [#539](https://gitlab.com/oauth-xx/oauth2/-/merge_requests/539) on main branch (@anderscarling)
 
 ## [1.4.5] - 2021-03-18
-- [#535](https://github.com/oauth-xx/oauth2/pull/535) - Compatibility with range of supported Ruby OpenSSL versions, Rubocop updates, Github Actions, analogous to [#536](https://github.com/oauth-xx/oauth2/pull/536) on main branch (@pboling)
-- [#518](https://github.com/oauth-xx/oauth2/pull/518) - Add extract_access_token option to OAuth2::Client (@jonspalmer)
-- [#507](https://github.com/oauth-xx/oauth2/pull/507) - Fix camel case content type, response keys (@anvox)
-- [#500](https://github.com/oauth-xx/oauth2/pull/500) - Fix YARD documentation formatting (@olleolleolle)
+- [#535](https://gitlab.com/oauth-xx/oauth2/-/merge_requests/535) - Compatibility with range of supported Ruby OpenSSL versions, Rubocop updates, Github Actions, analogous to [#536](https://gitlab.com/oauth-xx/oauth2/-/merge_requests/536) on main branch (@pboling)
+- [#518](https://gitlab.com/oauth-xx/oauth2/-/merge_requests/518) - Add extract_access_token option to OAuth2::Client (@jonspalmer)
+- [#507](https://gitlab.com/oauth-xx/oauth2/-/merge_requests/507) - Fix camel case content type, response keys (@anvox)
+- [#500](https://gitlab.com/oauth-xx/oauth2/-/merge_requests/500) - Fix YARD documentation formatting (@olleolleolle)
 
 ## [1.4.4] - 2020-02-12
-- [#408](https://github.com/oauth-xx/oauth2/pull/408) - Fixed expires_at for formatted time (@Lomey)
+- [#408](https://gitlab.com/oauth-xx/oauth2/-/merge_requests/408) - Fixed expires_at for formatted time (@Lomey)
 
 ## [1.4.3] - 2020-01-29
-- [#483](https://github.com/oauth-xx/oauth2/pull/483) - add project metadata to gemspec (@orien)
-- [#495](https://github.com/oauth-xx/oauth2/pull/495) - support additional types of access token requests (@SteveyblamFreeagent, @thomcorley, @dgholz)
+- [#483](https://gitlab.com/oauth-xx/oauth2/-/merge_requests/483) - add project metadata to gemspec (@orien)
+- [#495](https://gitlab.com/oauth-xx/oauth2/-/merge_requests/495) - support additional types of access token requests (@SteveyblamFreeagent, @thomcorley, @dgholz)
   - Adds support for private_key_jwt and tls_client_auth
-- [#433](https://github.com/oauth-xx/oauth2/pull/433) - allow field names with square brackets and numbers in params (@asm256)
+- [#433](https://gitlab.com/oauth-xx/oauth2/-/merge_requests/433) - allow field names with square brackets and numbers in params (@asm256)
 
 ## [1.4.2] - 2019-10-01
-- [#478](https://github.com/oauth-xx/oauth2/pull/478) - support latest version of faraday & fix build (@pboling)
+- [#478](https://gitlab.com/oauth-xx/oauth2/-/merge_requests/478) - support latest version of faraday & fix build (@pboling)
   - Officially support Ruby 2.6 and truffleruby
 
 ## [1.4.1] - 2018-10-13
-- [#417](https://github.com/oauth-xx/oauth2/pull/417) - update jwt dependency (@thewoolleyman)
-- [#419](https://github.com/oauth-xx/oauth2/pull/419) - remove rubocop dependency (temporary, added back in [#423](https://github.com/oauth-xx/oauth2/pull/423)) (@pboling)
-- [#418](https://github.com/oauth-xx/oauth2/pull/418) - update faraday dependency (@pboling)
-- [#420](https://github.com/oauth-xx/oauth2/pull/420) - update [oauth2.gemspec](https://github.com/oauth-xx/oauth2/blob/1-4-stable/oauth2.gemspec) (@pboling)
-- [#421](https://github.com/oauth-xx/oauth2/pull/421) - fix [CHANGELOG.md](https://github.com/oauth-xx/oauth2/blob/1-4-stable/CHANGELOG.md) for previous releases (@pboling)
-- [#422](https://github.com/oauth-xx/oauth2/pull/422) - update [LICENSE](https://github.com/oauth-xx/oauth2/blob/1-4-stable/LICENSE) and [README.md](https://github.com/oauth-xx/oauth2/blob/1-4-stable/README.md) (@pboling)
-- [#423](https://github.com/oauth-xx/oauth2/pull/423) - update [builds](https://travis-ci.org/oauth-xx/oauth2/builds), [Rakefile](https://github.com/oauth-xx/oauth2/blob/1-4-stable/Rakefile) (@pboling)
+- [#417](https://gitlab.com/oauth-xx/oauth2/-/merge_requests/417) - update jwt dependency (@thewoolleyman)
+- [#419](https://gitlab.com/oauth-xx/oauth2/-/merge_requests/419) - remove rubocop dependency (temporary, added back in [#423](https://gitlab.com/oauth-xx/oauth2/-/merge_requests/423)) (@pboling)
+- [#418](https://gitlab.com/oauth-xx/oauth2/-/merge_requests/418) - update faraday dependency (@pboling)
+- [#420](https://gitlab.com/oauth-xx/oauth2/-/merge_requests/420) - update [oauth2.gemspec](https://gitlab.com/oauth-xx/oauth2/-/blob/1-4-stable/oauth2.gemspec) (@pboling)
+- [#421](https://gitlab.com/oauth-xx/oauth2/-/merge_requests/421) - fix [CHANGELOG.md](https://gitlab.com/oauth-xx/oauth2/-/blob/1-4-stable/CHANGELOG.md) for previous releases (@pboling)
+- [#422](https://gitlab.com/oauth-xx/oauth2/-/merge_requests/422) - update [LICENSE](https://gitlab.com/oauth-xx/oauth2/-/blob/1-4-stable/LICENSE) and [README.md](https://gitlab.com/oauth-xx/oauth2/-/blob/1-4-stable/README.md) (@pboling)
+- [#423](https://gitlab.com/oauth-xx/oauth2/-/merge_requests/423) - update [builds](https://travis-ci.org/oauth-xx/oauth2/builds), [Rakefile](https://gitlab.com/oauth-xx/oauth2/-/blob/1-4-stable/Rakefile) (@pboling)
   - officially document supported Rubies
     * Ruby 1.9.3
     * Ruby 2.0.0
@@ -144,40 +144,40 @@ All notable changes to this project will be documented in this file.
 
 ## [0.0.4] + [0.0.3] + [0.0.2] + [0.0.1] - 2010-04-22
 
-[0.0.1]: https://github.com/oauth-xx/oauth2/compare/311d9f4...v0.0.1
-[0.0.2]: https://github.com/oauth-xx/oauth2/compare/v0.0.1...v0.0.2
-[0.0.3]: https://github.com/oauth-xx/oauth2/compare/v0.0.2...v0.0.3
-[0.0.4]: https://github.com/oauth-xx/oauth2/compare/v0.0.3...v0.0.4
-[0.0.5]: https://github.com/oauth-xx/oauth2/compare/v0.0.4...v0.0.5
-[0.0.6]: https://github.com/oauth-xx/oauth2/compare/v0.0.5...v0.0.6
-[0.0.7]: https://github.com/oauth-xx/oauth2/compare/v0.0.6...v0.0.7
-[0.0.8]: https://github.com/oauth-xx/oauth2/compare/v0.0.7...v0.0.8
-[0.0.9]: https://github.com/oauth-xx/oauth2/compare/v0.0.8...v0.0.9
-[0.0.10]: https://github.com/oauth-xx/oauth2/compare/v0.0.9...v0.0.10
-[0.0.11]: https://github.com/oauth-xx/oauth2/compare/v0.0.10...v0.0.11
-[0.0.12]: https://github.com/oauth-xx/oauth2/compare/v0.0.11...v0.0.12
-[0.0.13]: https://github.com/oauth-xx/oauth2/compare/v0.0.12...v0.0.13
-[0.1.0]: https://github.com/oauth-xx/oauth2/compare/v0.0.13...v0.1.0
-[0.1.1]: https://github.com/oauth-xx/oauth2/compare/v0.1.0...v0.1.1
-[0.2.0]: https://github.com/oauth-xx/oauth2/compare/v0.1.1...v0.2.0
-[0.3.0]: https://github.com/oauth-xx/oauth2/compare/v0.2.0...v0.3.0
-[0.4.0]: https://github.com/oauth-xx/oauth2/compare/v0.3.0...v0.4.0
-[0.4.1]: https://github.com/oauth-xx/oauth2/compare/v0.4.0...v0.4.1
-[0.5.0]: https://github.com/oauth-xx/oauth2/compare/v0.4.1...v0.5.0
-[1.0.0]: https://github.com/oauth-xx/oauth2/compare/v0.9.4...v1.0.0
-[1.1.0]: https://github.com/oauth-xx/oauth2/compare/v1.0.0...v1.1.0
-[1.2.0]: https://github.com/oauth-xx/oauth2/compare/v1.1.0...v1.2.0
-[1.3.0]: https://github.com/oauth-xx/oauth2/compare/v1.2.0...v1.3.0
-[1.3.1]: https://github.com/oauth-xx/oauth2/compare/v1.3.0...v1.3.1
-[1.4.0]: https://github.com/oauth-xx/oauth2/compare/v1.3.1...v1.4.0
-[1.4.1]: https://github.com/oauth-xx/oauth2/compare/v1.4.0...v1.4.1
-[1.4.2]: https://github.com/oauth-xx/oauth2/compare/v1.4.1...v1.4.2
-[1.4.3]: https://github.com/oauth-xx/oauth2/compare/v1.4.2...v1.4.3
-[1.4.4]: https://github.com/oauth-xx/oauth2/compare/v1.4.3...v1.4.4
-[1.4.5]: https://github.com/oauth-xx/oauth2/compare/v1.4.4...v1.4.5
-[1.4.6]: https://github.com/oauth-xx/oauth2/compare/v1.4.5...v1.4.6
-[1.4.7]: https://github.com/oauth-xx/oauth2/compare/v1.4.6...v1.4.7
-[1.4.8]: https://github.com/oauth-xx/oauth2/compare/v1.4.7...v1.4.8
-[1.4.9]: https://github.com/oauth-xx/oauth2/compare/v1.4.8...v1.4.9
-[1.4.10]: https://github.com/oauth-xx/oauth2/compare/v1.4.9...v1.4.10
-[unreleased]: https://github.com/oauth-xx/oauth2/compare/v1.4.10...HEAD
+[0.0.1]: https://gitlab.com/oauth-xx/oauth2/-/compare/311d9f4...v0.0.1
+[0.0.2]: https://gitlab.com/oauth-xx/oauth2/-/compare/v0.0.1...v0.0.2
+[0.0.3]: https://gitlab.com/oauth-xx/oauth2/-/compare/v0.0.2...v0.0.3
+[0.0.4]: https://gitlab.com/oauth-xx/oauth2/-/compare/v0.0.3...v0.0.4
+[0.0.5]: https://gitlab.com/oauth-xx/oauth2/-/compare/v0.0.4...v0.0.5
+[0.0.6]: https://gitlab.com/oauth-xx/oauth2/-/compare/v0.0.5...v0.0.6
+[0.0.7]: https://gitlab.com/oauth-xx/oauth2/-/compare/v0.0.6...v0.0.7
+[0.0.8]: https://gitlab.com/oauth-xx/oauth2/-/compare/v0.0.7...v0.0.8
+[0.0.9]: https://gitlab.com/oauth-xx/oauth2/-/compare/v0.0.8...v0.0.9
+[0.0.10]: https://gitlab.com/oauth-xx/oauth2/-/compare/v0.0.9...v0.0.10
+[0.0.11]: https://gitlab.com/oauth-xx/oauth2/-/compare/v0.0.10...v0.0.11
+[0.0.12]: https://gitlab.com/oauth-xx/oauth2/-/compare/v0.0.11...v0.0.12
+[0.0.13]: https://gitlab.com/oauth-xx/oauth2/-/compare/v0.0.12...v0.0.13
+[0.1.0]: https://gitlab.com/oauth-xx/oauth2/-/compare/v0.0.13...v0.1.0
+[0.1.1]: https://gitlab.com/oauth-xx/oauth2/-/compare/v0.1.0...v0.1.1
+[0.2.0]: https://gitlab.com/oauth-xx/oauth2/-/compare/v0.1.1...v0.2.0
+[0.3.0]: https://gitlab.com/oauth-xx/oauth2/-/compare/v0.2.0...v0.3.0
+[0.4.0]: https://gitlab.com/oauth-xx/oauth2/-/compare/v0.3.0...v0.4.0
+[0.4.1]: https://gitlab.com/oauth-xx/oauth2/-/compare/v0.4.0...v0.4.1
+[0.5.0]: https://gitlab.com/oauth-xx/oauth2/-/compare/v0.4.1...v0.5.0
+[1.0.0]: https://gitlab.com/oauth-xx/oauth2/-/compare/v0.9.4...v1.0.0
+[1.1.0]: https://gitlab.com/oauth-xx/oauth2/-/compare/v1.0.0...v1.1.0
+[1.2.0]: https://gitlab.com/oauth-xx/oauth2/-/compare/v1.1.0...v1.2.0
+[1.3.0]: https://gitlab.com/oauth-xx/oauth2/-/compare/v1.2.0...v1.3.0
+[1.3.1]: https://gitlab.com/oauth-xx/oauth2/-/compare/v1.3.0...v1.3.1
+[1.4.0]: https://gitlab.com/oauth-xx/oauth2/-/compare/v1.3.1...v1.4.0
+[1.4.1]: https://gitlab.com/oauth-xx/oauth2/-/compare/v1.4.0...v1.4.1
+[1.4.2]: https://gitlab.com/oauth-xx/oauth2/-/compare/v1.4.1...v1.4.2
+[1.4.3]: https://gitlab.com/oauth-xx/oauth2/-/compare/v1.4.2...v1.4.3
+[1.4.4]: https://gitlab.com/oauth-xx/oauth2/-/compare/v1.4.3...v1.4.4
+[1.4.5]: https://gitlab.com/oauth-xx/oauth2/-/compare/v1.4.4...v1.4.5
+[1.4.6]: https://gitlab.com/oauth-xx/oauth2/-/compare/v1.4.5...v1.4.6
+[1.4.7]: https://gitlab.com/oauth-xx/oauth2/-/compare/v1.4.6...v1.4.7
+[1.4.8]: https://gitlab.com/oauth-xx/oauth2/-/compare/v1.4.7...v1.4.8
+[1.4.9]: https://gitlab.com/oauth-xx/oauth2/-/compare/v1.4.8...v1.4.9
+[1.4.10]: https://gitlab.com/oauth-xx/oauth2/-/compare/v1.4.9...v1.4.10
+[unreleased]: https://gitlab.com/oauth-xx/oauth2/-/compare/v1.4.10...HEAD
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index ed315d0c..a0a0933b 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,6 +1,6 @@
 ## Contributing
 
-Bug reports and pull requests are welcome on GitHub at [https://github.com/oauth-xx/oauth2][source]
+Bug reports and pull requests are welcome on GitHub at [https://gitlab.com/oauth-xx/oauth2][source]
 . This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to
 the [code of conduct][conduct].
 
@@ -33,12 +33,12 @@ Made with [contributors-img][contrib-rocks].
 
 [comment]: <> (Following links are used by README, CONTRIBUTING)
 
-[conduct]: https://github.com/oauth-xx/oauth2/blob/main/CODE_OF_CONDUCT.md
+[conduct]: https://gitlab.com/oauth-xx/oauth2/-/blob/main/CODE_OF_CONDUCT.md
 
 [contrib-rocks]: https://contrib.rocks
 
-[contributors]: https://github.com/oauth-xx/oauth2/graphs/contributors
+[contributors]: https://gitlab.com/oauth-xx/oauth2/-/graphs/main
 
 [comment]: <> (Following links are used by README, CONTRIBUTING, Homepage)
 
-[source]: https://github.com/oauth-xx/oauth2/
+[source]: https://gitlab.com/oauth-xx/oauth2
diff --git a/README.md b/README.md
index 125c954b..a1bac1e1 100644
--- a/README.md
+++ b/README.md
@@ -19,7 +19,7 @@ See the sibling `oauth` gem for OAuth 1.0 implementations in Ruby.
 [supported-only-for-critical-enterprise-security-issues](#oauth2-for-enterprise) `1-4-stable`
 branch. Please do not use this, and instead upgrade to version 2! ⚠️⚠️⚠️
 
-No further releases of 1.x series are planned!  [Version 2](https://github.com/oauth-xx/oauth2#what-is-new-for-v20) has *tons* of improvements!
+No further releases of 1.x series are planned!  [Version 2](https://gitlab.com/oauth-xx/oauth2/#what-is-new-for-v20) has *tons* of improvements!
 
 If you must continue using 1.4.x please consider purchasing an open source security maintenance contract from [Tidelift][tidelift-ref].
 
@@ -29,7 +29,7 @@ If you must continue using 1.4.x please consider purchasing an open source secur
 * [OAuth 1.0 sibling gem][sibling-gem]
 
 [oauth2-spec]: https://oauth.net/2/
-[sibling-gem]: https://github.com/oauth-xx/oauth-ruby
+[sibling-gem]: https://gitlab.com/oauth-xx/oauth
 
 ## Release Documentation
 
@@ -38,17 +38,17 @@ If you must continue using 1.4.x please consider purchasing an open source secur
 
 | Version | Release Date | Readme                                                    |
 |---------|--------------|-----------------------------------------------------------|
-| 1.4.10  | Jul 1, 2022  | https://github.com/oauth-xx/oauth2/blob/v1.4.10/README.md |
-| 1.4.9   | Feb 20, 2022 | https://github.com/oauth-xx/oauth2/blob/v1.4.9/README.md  |
-| 1.4.8   | Feb 18, 2022 | https://github.com/oauth-xx/oauth2/blob/v1.4.8/README.md  |
-| 1.4.7   | Mar 19, 2021 | https://github.com/oauth-xx/oauth2/blob/v1.4.7/README.md  |
-| 1.4.6   | Mar 19, 2021 | https://github.com/oauth-xx/oauth2/blob/v1.4.6/README.md  |
-| 1.4.5   | Mar 18, 2021 | https://github.com/oauth-xx/oauth2/blob/v1.4.5/README.md  |
-| 1.4.4   | Feb 12, 2020 | https://github.com/oauth-xx/oauth2/blob/v1.4.4/README.md  |
-| 1.4.3   | Jan 29, 2020 | https://github.com/oauth-xx/oauth2/blob/v1.4.3/README.md  |
-| 1.4.2   | Oct 1, 2019  | https://github.com/oauth-xx/oauth2/blob/v1.4.2/README.md  |
-| 1.4.1   | Oct 13, 2018 | https://github.com/oauth-xx/oauth2/blob/v1.4.1/README.md  |
-| 1.4.0   | Jun 9, 2017  | https://github.com/oauth-xx/oauth2/blob/v1.4.0/README.md  |
+| 1.4.10  | Jul 1, 2022  | https://gitlab.com/oauth-xx/oauth2/-/blob/v1.4.10/README.md |
+| 1.4.9   | Feb 20, 2022 | https://gitlab.com/oauth-xx/oauth2/-/blob/v1.4.9/README.md  |
+| 1.4.8   | Feb 18, 2022 | https://gitlab.com/oauth-xx/oauth2/-/blob/v1.4.8/README.md  |
+| 1.4.7   | Mar 19, 2021 | https://gitlab.com/oauth-xx/oauth2/-/blob/v1.4.7/README.md  |
+| 1.4.6   | Mar 19, 2021 | https://gitlab.com/oauth-xx/oauth2/-/blob/v1.4.6/README.md  |
+| 1.4.5   | Mar 18, 2021 | https://gitlab.com/oauth-xx/oauth2/-/blob/v1.4.5/README.md  |
+| 1.4.4   | Feb 12, 2020 | https://gitlab.com/oauth-xx/oauth2/-/blob/v1.4.4/README.md  |
+| 1.4.3   | Jan 29, 2020 | https://gitlab.com/oauth-xx/oauth2/-/blob/v1.4.3/README.md  |
+| 1.4.2   | Oct 1, 2019  | https://gitlab.com/oauth-xx/oauth2/-/blob/v1.4.2/README.md  |
+| 1.4.1   | Oct 13, 2018 | https://gitlab.com/oauth-xx/oauth2/-/blob/v1.4.1/README.md  |
+| 1.4.0   | Jun 9, 2017  | https://gitlab.com/oauth-xx/oauth2/-/blob/v1.4.0/README.md  |
 </details>
 
 <details>
@@ -56,8 +56,8 @@ If you must continue using 1.4.x please consider purchasing an open source secur
 
 | Version  | Release Date | Readme                                                   |
 |----------|--------------|----------------------------------------------------------|
-| 1.3.1    | Mar 3, 2017  | https://github.com/oauth-xx/oauth2/blob/v1.3.1/README.md |
-| 1.3.0    | Dec 27, 2016 | https://github.com/oauth-xx/oauth2/blob/v1.3.0/README.md |
+| 1.3.1    | Mar 3, 2017  | https://gitlab.com/oauth-xx/oauth2/-/blob/v1.3.1/README.md |
+| 1.3.0    | Dec 27, 2016 | https://gitlab.com/oauth-xx/oauth2/-/blob/v1.3.0/README.md |
 </details>
 
 <details>
@@ -65,10 +65,10 @@ If you must continue using 1.4.x please consider purchasing an open source secur
 
 | Version  | Release Date | Readme                                                   |
 |----------|--------------|----------------------------------------------------------|
-| 1.2.0    | Jun 30, 2016 | https://github.com/oauth-xx/oauth2/blob/v1.2.0/README.md |
-| 1.1.0    | Jan 30, 2016 | https://github.com/oauth-xx/oauth2/blob/v1.1.0/README.md |
-| 1.0.0    | May 23, 2014 | https://github.com/oauth-xx/oauth2/blob/v1.0.0/README.md |
-| < 1.0.0  | Find here    | https://github.com/oauth-xx/oauth2/tags                  |
+| 1.2.0    | Jun 30, 2016 | https://gitlab.com/oauth-xx/oauth2/-/blob/v1.2.0/README.md |
+| 1.1.0    | Jan 30, 2016 | https://gitlab.com/oauth-xx/oauth2/-/blob/v1.1.0/README.md |
+| 1.0.0    | May 23, 2014 | https://gitlab.com/oauth-xx/oauth2/-/blob/v1.0.0/README.md |
+| < 1.0.0  | Find here    | https://gitlab.com/oauth-xx/oauth2/-/tags                  |
 </details>
 
 ## Status
@@ -100,15 +100,15 @@ appended indicators:
 ♻️ - URL needs to be updated from SASS integration. Find / Replace is insufficient.
 -->
 
-|     | Project               | bundle add oauth2                                                                                                                                                                                                                                                                            |
-|:----|-----------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| 1️⃣ | name, license, docs   | [![RubyGems.org][⛳️name-img]][⛳️gem] [![License: MIT][🖇src-license-img]][🖇src-license] [![FOSSA][🏘fossa-img]][🏘fossa] [![RubyDoc.info][🚎yard-img]][🚎yard] [![InchCI][🖐inch-ci-img]][🚎yard]                                                                                           |
-| 2️⃣ | version & activity    | [![Gem Version][⛳️version-img]][⛳️gem] [![Total Downloads][🖇DL-total-img]][⛳️gem] [![Download Rank][🏘DL-rank-img]][⛳️gem] [![Source Code][🚎src-home-img]][🚎src-home] [![Open PRs][🖐prs-o-img]][🖐prs-o] [![Closed PRs][🧮prs-c-img]][🧮prs-c] [![Next Version][📗next-img♻️]][📗next♻️] |
-| 3️⃣ | maintanence & linting | [![Maintainability][⛳cclim-maint-img♻️]][⛳cclim-maint] [![Helpers][🖇triage-help-img]][🖇triage-help] [![Depfu][🏘depfu-img♻️]][🏘depfu♻️] [![Contributors][🚎contributors-img]][🚎contributors] [![Style][🖐style-wf-img]][🖐style-wf] [![Kloc Roll][🧮kloc-img]][🧮kloc]                   |
-| 4️⃣ | testing               | [![Open Issues][⛳iss-o-img]][⛳iss-o] [![Closed Issues][🖇iss-c-img]][🖇iss-c] [![Supported][🏘sup-wf-img]][🏘sup-wf] [![Heads][🚎heads-wf-img]][🚎heads-wf] [![Unofficial Support][🖐uns-wf-img]][🖐uns-wf] [![MacOS][🧮mac-wf-img]][🧮mac-wf] [![Windows][📗win-wf-img]][📗win-wf]          |
-| 5️⃣ | coverage & security   | [![CodeClimate][⛳cclim-cov-img♻️]][⛳cclim-cov] [![CodeCov][🖇codecov-img♻️]][🖇codecov] [![Coveralls][🏘coveralls-img]][🏘coveralls] [![Security Policy][🚎sec-pol-img]][🚎sec-pol] [![CodeQL][🖐codeQL-img]][🖐codeQL] [![Code Coverage][🧮cov-wf-img]][🧮cov-wf]                           |
-| 6️⃣ | resources             | [![Discussion][⛳gh-discussions-img]][⛳gh-discussions] [![Get help on Codementor][🖇codementor-img]][🖇codementor] [![Chat][🏘chat-img]][🏘chat] [![Blog][🚎blog-img]][🚎blog] [![Blog][🖐wiki-img]][🖐wiki]                                                                                  |
-| 7️⃣ | spread 💖             | [![Liberapay Patrons][⛳liberapay-img]][⛳liberapay] [![Sponsor Me][🖇sponsor-img]][🖇sponsor] [![Tweet @ Peter][🏘tweet-img]][🏘tweet] [🌏][aboutme] [👼][angelme] [💻][coderme]                                                                                                              |
+|     | Project               | bundle add oauth2                                                                                                                                                                                                                                                          |
+|:----|-----------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| 1️⃣ | name, license, docs   | [![RubyGems.org][⛳️name-img]][⛳️gem] [![License: MIT][🖇src-license-img]][🖇src-license] [![FOSSA][🏘fossa-img]][🏘fossa] [![RubyDoc.info][🚎yard-img]][🚎yard] [![InchCI][🖐inch-ci-img]][🚎yard]                                                                         |
+| 2️⃣ | version & activity    | [![Gem Version][⛳️version-img]][⛳️gem] [![Total Downloads][🖇DL-total-img]][⛳️gem] [![Download Rank][🏘DL-rank-img]][⛳️gem] [![Source Code][🚎src-home-img]][🚎src-home]                                                                                                   |
+| 3️⃣ | maintanence & linting | [![Maintainability][⛳cclim-maint-img♻️]][⛳cclim-maint] [![Helpers][🖇triage-help-img]][🖇triage-help] [![Depfu][🏘depfu-img♻️]][🏘depfu♻️] [![Contributors][🚎contributors-img]][🚎contributors] [![Style][🖐style-wf-img]][🖐style-wf] [![Kloc Roll][🧮kloc-img]][🧮kloc] |
+| 4️⃣ | testing               | [![Supported][🏘sup-wf-img]][🏘sup-wf] [![Heads][🚎heads-wf-img]][🚎heads-wf] [![Unofficial Support][🖐uns-wf-img]][🖐uns-wf] [![MacOS][🧮mac-wf-img]][🧮mac-wf] [![Windows][📗win-wf-img]][📗win-wf]                                                                      |
+| 5️⃣ | coverage & security   | [![CodeClimate][⛳cclim-cov-img♻️]][⛳cclim-cov] [![CodeCov][🖇codecov-img♻️]][🖇codecov] [![Coveralls][🏘coveralls-img]][🏘coveralls] [![Security Policy][🚎sec-pol-img]][🚎sec-pol] [![CodeQL][🖐codeQL-img]][🖐codeQL] [![Code Coverage][🧮cov-wf-img]][🧮cov-wf]         |
+| 6️⃣ | resources             | [![Discussion][⛳gg-discussions-img]][⛳gg-discussions] [![Get help on Codementor][🖇codementor-img]][🖇codementor] [![Chat][🏘chat-img]][🏘chat] [![Blog][🚎blog-img]][🚎blog] [![Blog][🖐wiki-img]][🖐wiki]                                                                |
+| 7️⃣ | spread 💖             | [![Liberapay Patrons][⛳liberapay-img]][⛳liberapay] [![Sponsor Me][🖇sponsor-img]][🖇sponsor] [![Tweet @ Peter][🏘tweet-img]][🏘tweet] [🌏][aboutme] [👼][angelme] [💻][coderme]                                                                                            |
 
 <!--
 The link tokens in the following sections should be kept ordered by the row and badge numbering scheme
@@ -129,14 +129,8 @@ The link tokens in the following sections should be kept ordered by the row and
 [⛳️version-img]: http://img.shields.io/gem/v/oauth2.svg
 [🖇DL-total-img]: https://img.shields.io/gem/dt/oauth2.svg
 [🏘DL-rank-img]: https://img.shields.io/gem/rt/oauth2.svg
-[🚎src-home]: https://github.com/oauth-xx/oauth2
-[🚎src-home-img]: https://img.shields.io/badge/source-github-brightgreen.svg?style=flat
-[🖐prs-o]: https://github.com/oauth-xx/oauth2/pulls
-[🖐prs-o-img]: https://img.shields.io/github/issues-pr/oauth-xx/oauth2
-[🧮prs-c]: https://github.com/oauth-xx/oauth2/pulls?q=is%3Apr+is%3Aclosed
-[🧮prs-c-img]: https://img.shields.io/github/issues-pr-closed/oauth-xx/oauth2
-[📗next♻️]: https://github.com/oauth-xx/oauth2/milestone/2
-[📗next-img♻️]: https://img.shields.io/github/milestones/progress/oauth-xx/oauth2/2?label=Next%20Version
+[🚎src-home]: https://gitlab.com/oauth-xx/oauth2/
+[🚎src-home-img]: https://img.shields.io/badge/source-gitlab-blue.svg?style=flat
 
 <!-- 3️⃣ maintenance & linting -->
 [⛳cclim-maint]: https://codeclimate.com/github/oauth-xx/oauth2/maintainability
@@ -145,7 +139,7 @@ The link tokens in the following sections should be kept ordered by the row and
 [🖇triage-help-img]: https://www.codetriage.com/oauth-xx/oauth2/badges/users.svg
 [🏘depfu♻️]: https://depfu.com/github/oauth-xx/oauth2?project_id=4445
 [🏘depfu-img♻️]: https://badges.depfu.com/badges/6d34dc1ba682bbdf9ae2a97848241743/count.svg
-[🚎contributors]: https://github.com/oauth-xx/oauth2/graphs/contributors
+[🚎contributors]: https://gitlab.com/oauth-xx/oauth2/-/graphs/main
 [🚎contributors-img]: https://img.shields.io/github/contributors-anon/oauth-xx/oauth2
 [🖐style-wf]: https://github.com/oauth-xx/oauth2/actions/workflows/style.yml
 [🖐style-wf-img]: https://github.com/oauth-xx/oauth2/actions/workflows/style.yml/badge.svg
@@ -153,10 +147,6 @@ The link tokens in the following sections should be kept ordered by the row and
 [🧮kloc-img]: https://img.shields.io/tokei/lines/github.com/oauth-xx/oauth2
 
 <!-- 4️⃣ testing -->
-[⛳iss-o]: https://github.com/oauth-xx/oauth2/issues
-[⛳iss-o-img]: https://img.shields.io/github/issues-raw/oauth-xx/oauth2
-[🖇iss-c]: https://github.com/oauth-xx/oauth2/issues?q=is%3Aissue+is%3Aclosed
-[🖇iss-c-img]: https://img.shields.io/github/issues-closed-raw/oauth-xx/oauth2
 [🏘sup-wf]: https://github.com/oauth-xx/oauth2/actions/workflows/supported.yml
 [🏘sup-wf-img]: https://github.com/oauth-xx/oauth2/actions/workflows/supported.yml/badge.svg
 [🚎heads-wf]: https://github.com/oauth-xx/oauth2/actions/workflows/heads.yml
@@ -175,7 +165,7 @@ The link tokens in the following sections should be kept ordered by the row and
 [🖇codecov]: https://codecov.io/gh/oauth-xx/oauth2
 [🏘coveralls]: https://coveralls.io/github/oauth-xx/oauth2?branch=1-4-stable
 [🏘coveralls-img]: https://coveralls.io/repos/github/oauth-xx/oauth2/badge.svg?branch=1-4-stable
-[🚎sec-pol]: https://github.com/oauth-xx/oauth2/blob/main/SECURITY.md
+[🚎sec-pol]: https://gitlab.com/oauth-xx/oauth2/-/blob/main/SECURITY.md
 [🚎sec-pol-img]: https://img.shields.io/badge/security-policy-brightgreen.svg?style=flat
 [🖐codeQL]: https://github.com/oauth-xx/oauth2/security/code-scanning
 [🖐codeQL-img]: https://github.com/oauth-xx/oauth2/actions/workflows/codeql-analysis.yml/badge.svg
@@ -183,15 +173,15 @@ The link tokens in the following sections should be kept ordered by the row and
 [🧮cov-wf-img]: https://github.com/oauth-xx/oauth2/actions/workflows/coverage.yml/badge.svg
 
 <!-- 6️⃣ resources -->
-[⛳gh-discussions]: https://github.com/oauth-xx/oauth2/discussions
-[⛳gh-discussions-img]: https://img.shields.io/github/discussions/oauth-xx/oauth2
+[⛳gg-discussions]: https://groups.google.com/g/oauth-ruby
+[⛳gg-discussions-img]: https://img.shields.io/badge/google-group-purple.svg?style=flat
 [🖇codementor]: https://www.codementor.io/peterboling?utm_source=github&utm_medium=button&utm_term=peterboling&utm_campaign=github
 [🖇codementor-img]: https://cdn.codementor.io/badges/get_help_github.svg
 [🏘chat]: https://gitter.im/oauth-xx/oauth2
 [🏘chat-img]: https://img.shields.io/gitter/room/oauth-xx/oauth2.svg
 [🚎blog]: http://www.railsbling.com/tags/oauth2/
 [🚎blog-img]: https://img.shields.io/badge/blog-railsbling-brightgreen.svg?style=flat
-[🖐wiki]: https://github.com/oauth-xx/oauth2/wiki
+[🖐wiki]: https://gitlab.com/oauth-xx/oauth2/-/wikis/home
 [🖐wiki-img]: https://img.shields.io/badge/wiki-examples-brightgreen.svg?style=flat
 
 <!-- 7️⃣ spread 💖 -->
@@ -246,18 +236,18 @@ For more see [SECURITY.md][🚎sec-pol].
 - Support [OIDC 1.0 Private Key JWT](https://openid.net/specs/openid-connect-core-1_0.html#ClientAuthentication); based on the OAuth JWT assertion specification [(RFC 7523)](https://tools.ietf.org/html/rfc7523)
 - Support new formats, including from [jsonapi.org](http://jsonapi.org/format/): `application/vdn.api+json`, `application/vnd.collection+json`, `application/hal+json`, `application/problem+json`
 - Adds new option to `OAuth2::Client#get_token`:
-  - `:access_token_class` (`AccessToken`); user specified class to use for all calls to `get_token`
+    - `:access_token_class` (`AccessToken`); user specified class to use for all calls to `get_token`
 - Adds new option to `OAuth2::AccessToken#initialize`:
-  - `:expires_latency` (`nil`); number of seconds by which AccessToken validity will be reduced to offset latency
+    - `:expires_latency` (`nil`); number of seconds by which AccessToken validity will be reduced to offset latency
 - By default, keys are transformed to camel case.
   - Original keys will still work as previously, in most scenarios, thanks to `rash_alt` gem.
   - However, this is a _breaking_ change if you rely on `response.parsed.to_h`, as the keys in the result will be camel case.
   - As of version 2.0.4 you can turn key transformation off with the `snaky: false` option.
 - By default, the `:auth_scheme` is now `:basic_auth` (instead of `:request_body`)
   - Third-party strategies and gems may need to be updated if a provider was requiring client id/secret in the request body
-- [... A lot more](https://github.com/oauth-xx/oauth2/blob/main/CHANGELOG.md#2.0.0)
+- [... A lot more](https://gitlab.com/oauth-xx/oauth2/-/blob/main/CHANGELOG.md#2.0.0)
 
-## Compatibility for v1.4.x series
+## Compatibility
 
 Targeted ruby compatibility is 2.7, 3.0 and 3.1. Compatibility is further distinguished by
 supported and unsupported versions of Ruby.
@@ -271,8 +261,7 @@ This gem is tested against MRI, JRuby, and Truffleruby.
 Each of those has varying versions that target a specific version of MRI Ruby.
 This gem should work in the just-listed Ruby engines according to the targeted MRI compatibility in the table below.
 If you would like to add support for additional engines,
-  first make sure Github Actions supports the engine,
-  then submit a PR to the correct maintenance branch as according to the table below.
+  see `gemfiles/README.md`, then submit a PR to the correct maintenance branch as according to the table below.
 </details>
 
 <details>
@@ -434,8 +423,8 @@ spec.add_dependency 'oauth2', '~> 1.4'
 
 [![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Foauth-xx%2Foauth2.svg?type=large)][fossa2]
 
-[license]: https://github.com/oauth-xx/oauth2/blob/main/LICENSE
-[oauth-xx]: https://github.com/oauth-xx
+[license]: https://gitlab.com/oauth-xx/oauth2/-/blob/main/LICENSE
+[oauth-xx]: https://gitlab.com/oauth-xx
 [fossa2]: https://app.fossa.io/projects/git%2Bgithub.com%2Foauth-xx%2Foauth2?ref=badge_large
 
 ## Development
@@ -448,14 +437,14 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
 
 See [CONTRIBUTING.md][contributing]
 
-[contributing]: https://github.com/oauth-xx/oauth2/blob/main/CONTRIBUTING.md
+[contributing]: https://gitlab.com/oauth-xx/oauth2/-/blob/main/CONTRIBUTING.md
 
 ## Contributors
 
-[![Contributors](https://contrib.rocks/image?repo=oauth-xx/oauth2)]("https://github.com/oauth-xx/oauth2/graphs/contributors")
+[![Contributors](https://contrib.rocks/image?repo=oauth-xx/oauth2)]("https://gitlab.com/oauth-xx/oauth2/-/graphs/main")
 
 Made with [contributors-img](https://contrib.rocks).
 
 ## Code of Conduct
 
-Everyone interacting in the OAuth2 project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/oauth-xx/oauth2/blob/main/CODE_OF_CONDUCT.md).
+Everyone interacting in the OAuth2 project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://gitlab.com/oauth-xx/oauth2/-/blob/main/CODE_OF_CONDUCT.md).

From 3b44a4c75bd74a6b927bbe33edeb39ee032547fd Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Fri, 16 Sep 2022 11:43:34 +0700
Subject: [PATCH 158/163] =?UTF-8?q?=F0=9F=92=84=20Rubocop=20linting?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 bin/bundle     | 2 +-
 oauth2.gemspec | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/bin/bundle b/bin/bundle
index fece50fe..fe8b5051 100755
--- a/bin/bundle
+++ b/bin/bundle
@@ -11,7 +11,7 @@
 require 'rubygems'
 
 m = Module.new do
-module_function
+    module_function
 
   def invoked_as_script?
     File.expand_path($PROGRAM_NAME) == File.expand_path(__FILE__)
diff --git a/oauth2.gemspec b/oauth2.gemspec
index 08580113..01ebfa53 100644
--- a/oauth2.gemspec
+++ b/oauth2.gemspec
@@ -47,7 +47,7 @@ Please upgrade, report issues, and support the project! Thanks, |7eter l-|. l3ol
   spec.metadata['bug_tracker_uri'] = "#{spec.homepage}/-/issues"
   spec.metadata['documentation_uri'] = "https://www.rubydoc.info/gems/#{spec.name}/#{spec.version}"
   spec.metadata['wiki_uri'] = "#{spec.homepage}/-/wiki"
-  spec.metadata['funding_uri'] = "https://liberapay.com/pboling"
+  spec.metadata['funding_uri'] = 'https://liberapay.com/pboling'
   spec.metadata['rubygems_mfa_required'] = 'true'
 
   spec.require_paths = %w[lib]

From 581793722006df403217b450000e06cadbb625c4 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Fri, 16 Sep 2022 11:53:49 +0700
Subject: [PATCH 159/163] =?UTF-8?q?=F0=9F=94=96=20Prepare=20release=201.4.?=
 =?UTF-8?q?11?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 CHANGELOG.md          | 7 ++++++-
 lib/oauth2/version.rb | 2 +-
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index d918fdf1..e445e555 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,6 +3,10 @@ All notable changes to this project will be documented in this file.
 
 ## [unreleased]
 
+## [1.4.11] - 2022-09-16
+- Complete migration to main branch as default (@pboling)
+- Complete migration to Gitlab, updating all links, and references in VCS-managed files (@pboling) 
+
 ## [1.4.10] - 2022-07-01
 - FIPS Compatibility [#587](https://gitlab.com/oauth-xx/oauth2/-/merge_requests/587) (@akostadinov)
 
@@ -180,4 +184,5 @@ All notable changes to this project will be documented in this file.
 [1.4.8]: https://gitlab.com/oauth-xx/oauth2/-/compare/v1.4.7...v1.4.8
 [1.4.9]: https://gitlab.com/oauth-xx/oauth2/-/compare/v1.4.8...v1.4.9
 [1.4.10]: https://gitlab.com/oauth-xx/oauth2/-/compare/v1.4.9...v1.4.10
-[unreleased]: https://gitlab.com/oauth-xx/oauth2/-/compare/v1.4.10...HEAD
+[1.4.11]: https://gitlab.com/oauth-xx/oauth2/-/compare/v1.4.10...v1.4.11
+[unreleased]: https://gitlab.com/oauth-xx/oauth2/-/compare/v1.4.11...HEAD
diff --git a/lib/oauth2/version.rb b/lib/oauth2/version.rb
index 7b1e7c9f..44885708 100644
--- a/lib/oauth2/version.rb
+++ b/lib/oauth2/version.rb
@@ -24,7 +24,7 @@ def minor
     #
     # @return [Integer]
     def patch
-      10
+      11
     end
 
     # The pre-release version, if any

From f7035bc7a5840fc8cff8a12aee9935ff4dec3d0c Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Fri, 16 Sep 2022 11:54:28 +0700
Subject: [PATCH 160/163] =?UTF-8?q?=F0=9F=94=A7=20Migration=20from=20Githu?=
 =?UTF-8?q?b=20to=20Gitlab?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 LICENSE | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/LICENSE b/LICENSE
index 0d3a82cd..5fd4bd3c 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,7 +1,7 @@
 MIT License
 
 Copyright (c) 2011 - 2013 Michael Bleigh and Intridea, Inc.
-Copyright (c) 2017 - 2022 oauth-xx organization, https://github.com/oauth-xx
+Copyright (c) 2017 - 2022 oauth-xx organization, https://gitlab.com/oauth-xx
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal

From d41fb6e8feef3b0b0382dedc0ede82f5ca7854cd Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Fri, 16 Sep 2022 12:01:41 +0700
Subject: [PATCH 161/163] =?UTF-8?q?=F0=9F=94=96=20Prepare=20release=201.4.?=
 =?UTF-8?q?11?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 README.md | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/README.md b/README.md
index a1bac1e1..13f534b8 100644
--- a/README.md
+++ b/README.md
@@ -36,8 +36,9 @@ If you must continue using 1.4.x please consider purchasing an open source secur
 <details>
   <summary>1.4.x Readmes</summary>
 
-| Version | Release Date | Readme                                                    |
-|---------|--------------|-----------------------------------------------------------|
+| Version | Release Date | Readme                                                      |
+|---------|--------------|-------------------------------------------------------------|
+| 1.4.11  | Sep 16, 2022 | https://gitlab.com/oauth-xx/oauth2/-/blob/v1.4.11/README.md |
 | 1.4.10  | Jul 1, 2022  | https://gitlab.com/oauth-xx/oauth2/-/blob/v1.4.10/README.md |
 | 1.4.9   | Feb 20, 2022 | https://gitlab.com/oauth-xx/oauth2/-/blob/v1.4.9/README.md  |
 | 1.4.8   | Feb 18, 2022 | https://gitlab.com/oauth-xx/oauth2/-/blob/v1.4.8/README.md  |

From 2466989ad0918cd92523e5cf50502c47807035ac Mon Sep 17 00:00:00 2001
From: Damian Aberbuj <daberbuj@keepcon.com>
Date: Mon, 26 Jun 2023 15:24:43 -0300
Subject: [PATCH 162/163] 431/fix post json for token in v1.4

---
 lib/oauth2/client.rb | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/lib/oauth2/client.rb b/lib/oauth2/client.rb
index e6160c53..2b9d5558 100644
--- a/lib/oauth2/client.rb
+++ b/lib/oauth2/client.rb
@@ -166,7 +166,11 @@ def get_token(params, access_token_opts = {}, extract_access_token = options[:ex
       opts = {:raise_errors => options[:raise_errors], :parse => params.delete(:parse)}
       headers = params.delete(:headers) || {}
       if options[:token_method] == :post
-        opts[:body] = params
+        opts[:body] = if headers['Content-Type'] == 'application/json'
+                        params.to_json
+                      else
+                        params
+                      end
         opts[:headers] = {'Content-Type' => 'application/x-www-form-urlencoded'}
       else
         opts[:params] = params

From dfe26e3ac930644a056c2654db19a016edbf2751 Mon Sep 17 00:00:00 2001
From: Peter Boling <peter.boling@gmail.com>
Date: Tue, 8 Aug 2023 00:08:28 -0600
Subject: [PATCH 163/163] =?UTF-8?q?=F0=9F=93=9D=20Fix=20What?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 README.md | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/README.md b/README.md
index 13f534b8..6b78b998 100644
--- a/README.md
+++ b/README.md
@@ -11,8 +11,8 @@
 
 OAuth 2.0 is the industry-standard protocol for authorization.
 OAuth 2.0 focuses on client developer simplicity while providing specific authorization flows for web applications,
-    desktop applications, mobile phones, and living room devices.
-This is a RubyGem for implementing OAuth 2.0 clients and servers in Ruby applications.
+desktop applications, mobile phones, and living room devices.
+This is a RubyGem for implementing OAuth 2.0 clients (not servers) in Ruby applications.
 See the sibling `oauth` gem for OAuth 1.0 implementations in Ruby.
 
 ⚠️⚠️⚠️ **_WARNING_**: You are viewing the `README` of the 
