firebase_id_token 2.3.1 → 2.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 536ac169a34db614f7501d80d974dbd9048a917bb3c0887b6e16f90381772b61
4
- data.tar.gz: 83e7a5258af798b479f1a9eea253e4d0dfae6cac5aa0f003787973abb87dc28d
3
+ metadata.gz: d323f3f19f0e2cfa9f511adac526f38261ee28386d4abc210a22e26358008143
4
+ data.tar.gz: 82095062bbd88ebfe9ddbee3f769f2bc9e4fb0b9289fa673f4bf81d6a24132d0
5
5
  SHA512:
6
- metadata.gz: 1e721876bcfa5f946236d42461bae05365adbfe61c37fd744029fc1e2b27b3c1fe22bc20bf850a6a23fbd18d4e45f2a2572190a76fc86ef5ad022f689ace8d6a
7
- data.tar.gz: d06b0c0f60dc2dfe15762ba19fc9ef9549f3efcd46bc124ab0572ba992993fdd06cfd59a3aea8c0708d56916eba3551dade16026ee57fa7ddd1fe103fbf48d5c
6
+ metadata.gz: 5d056894ee1051fb9ccb0984624282805f153aca7e9bb41b5d3b39a93b749150311e45e11f7e182fdb4ee1814bea722a5fc49ddb975394f319edb3bbea7424d6
7
+ data.tar.gz: 998d1b74cdf9b036892e12ab9e7c271417ead8d18c6bbb8dcea04ea555c4fe6a856b79840872676c4aa530726132826f795c686ba5096502004a22ab7df82751
data/.travis.yml CHANGED
@@ -1,7 +1,7 @@
1
1
  sudo: false
2
2
  language: ruby
3
3
  rvm:
4
- - 2.4.0
5
- before_install: gem install bundler -v 1.14.6
4
+ - 2.6.3
5
+ before_install: gem install bundler -v 1.17.2
6
6
  services:
7
7
  - redis-server
data/CHANGELOG.md ADDED
@@ -0,0 +1,121 @@
1
+ # Changelog
2
+ All notable changes to this project will be documented in this file.
3
+
4
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
5
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
+
7
+ ## [Unreleased]
8
+
9
+ ## [2.5.0] - 2022-04-13
10
+
11
+ ### Fixed
12
+ - Local Code Execution through Argument Injection via dash leading git url parameter in Gemfile [CVE-2021-43809](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-43809).
13
+ - Dependency Confusion in Bundler [CVE-2020-36327](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-36327).
14
+ - Insecure path handling in Bundler [CVE-2019-3881](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-3881).
15
+
16
+ ### Changed
17
+ - Using Bundler 2.3.11.
18
+ - Using `Time.current` instead of `Time.now` to work with timezones [PR 34](https://github.com/fschuindt/firebase_id_token/pull/34).
19
+ - Caching certificates on memory using `Thread` to avoid unnecessary calls into Redis [PR 33](https://github.com/fschuindt/firebase_id_token/pull/33).
20
+
21
+ ## [2.4.0] - 2020-05-02
22
+
23
+ ### Fixed
24
+ - Rake development dependency vulnerability [CVE-2020-8130](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-8130).
25
+
26
+ ### Changed
27
+ - Using Bundler 1.17.2.
28
+
29
+ ### Added
30
+ - Ability to raise errors when verifying tokens.
31
+ - `FirebaseIdToken::Certificates.find!` method.
32
+ - `FirebaseIdToken::Signatures.verify!` method.
33
+ - `FirebaseIdToken::Exceptions::CertificateNotFound` exception.
34
+ - `:raise_error` option to `FirebaseIdToken::Signature.verify`.
35
+ - `CHANGELOG.md` file.
36
+
37
+ ## [2.3.2] - 2020-02-15
38
+
39
+ ### Fixed
40
+ - Certificate fixture not accessible when packing Gem into Rails application.
41
+
42
+ ### Changed
43
+ - Bumped Bundler version to 1.14.
44
+
45
+ ## [2.3.1] - 2019-08-13
46
+
47
+ ### Fixed
48
+ - Certificate fixture reading issue.
49
+
50
+ ### Added
51
+ - Test mode.
52
+ - Test mode documentation.
53
+
54
+ ## [2.3.0] - 2018-06-18
55
+
56
+ ### Changed
57
+ - Started to use [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
58
+ - Runtime dependencies versions upgraded.
59
+ - Use Redis `>= 3.3.3`.
60
+
61
+ ## [2.2.0] - 2018-05-21
62
+ *Nothing tracked, release skipped.*
63
+
64
+ ## [2.1.0] - 2018-04-09
65
+
66
+ ### Fixed
67
+ - `FirebaseIdToken::Signature.verify` now returns `nil` for newly issued tokens.
68
+
69
+ ## [2.0.0] - 2017-12-09
70
+
71
+ ### Fixed
72
+ - Typo on Rake task `force_request` name.
73
+
74
+ ## [1.3.0] - 2017-09-15
75
+
76
+ ### Changed
77
+ - Renamed `Certificates.request_anyway` to `Certificates.request!` (`Certificates.request_anyway` was kept for backwards compatibility.
78
+
79
+ ### Fixed
80
+ - Documentaiton typos.
81
+ - Initializer typos.
82
+
83
+ ## [1.2.2] - 2017-04-29
84
+
85
+ ### Changed
86
+ - Recommended people to use cron tasks instead of background jobs.
87
+ - Set certificates TTL based on cache-control's max-age.
88
+ - Documentation now warns about request during application start in Rails.
89
+
90
+ ### Fixed
91
+ - Documentation typos.
92
+
93
+ ## [1.2.1] - 2017-04-27
94
+
95
+ ### Changed
96
+ - Small improvements on documentation.
97
+
98
+ ## [1.2.0] - 2017-04-26
99
+
100
+ ### Changed
101
+ - The Gem was marked as "ready to use".
102
+
103
+ ## [1.1.0] - 2017-04-26
104
+ *Nothing tracked.*
105
+
106
+ ## [1.0.0] - 2017-04-26
107
+ *Version removed.*
108
+
109
+ ## [0.1.0] - 2017-04-23
110
+ *Version removed.*
111
+
112
+ [2.5.0]: https://github.com/fschuindt/firebase_id_token/compare/2.4.0...2.5.0
113
+ [2.4.0]: https://github.com/fschuindt/firebase_id_token/compare/2.3.2...2.4.0
114
+ [2.3.2]: https://github.com/fschuindt/firebase_id_token/compare/2.3.1...2.3.2
115
+ [2.3.1]: https://github.com/fschuindt/firebase_id_token/compare/2.3.0...2.3.1
116
+ [2.3.0]: https://github.com/fschuindt/firebase_id_token/compare/2.0.0...2.3.0
117
+ [2.1.0]: https://github.com/fschuindt/firebase_id_token/compare/2.0.0...2.1.0
118
+ [2.0.0]: https://github.com/fschuindt/firebase_id_token/compare/1.3.0...2.0.0
119
+ [1.3.0]: https://github.com/fschuindt/firebase_id_token/compare/1.2.2...1.3.0
120
+ [1.2.2]: https://github.com/fschuindt/firebase_id_token/compare/1.2.1...1.2.2
121
+ [1.2.1]: https://github.com/fschuindt/firebase_id_token/compare/1.2.0...1.2.1
data/README.md CHANGED
@@ -29,7 +29,7 @@ gem install firebase_id_token
29
29
 
30
30
  or in your Gemfile
31
31
  ```
32
- gem 'firebase_id_token', '~> 2.3.1'
32
+ gem 'firebase_id_token', '~> 2.5.0'
33
33
  ```
34
34
  then
35
35
  ```
@@ -0,0 +1,9 @@
1
+ version: '3'
2
+
3
+ services:
4
+ redis:
5
+ image: redis:5-alpine
6
+ ports:
7
+ - "6379:6379"
8
+ expose:
9
+ - 6379
@@ -17,15 +17,13 @@ Gem::Specification.new do |spec|
17
17
  spec.homepage = 'https://github.com/fschuindt/firebase_id_token'
18
18
  spec.license = 'MIT'
19
19
 
20
- spec.files = `git ls-files -z`.split("\x0").reject do |f|
21
- f.match(%r{^(test|spec|features)/})
22
- end
20
+ spec.files = `git ls-files -z`.split("\x0")
23
21
  spec.bindir = 'exe'
24
22
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
25
23
  spec.require_paths = ['lib']
26
24
 
27
- spec.add_development_dependency 'bundler', '~> 1.14'
28
- spec.add_development_dependency 'rake', '~> 10.0'
25
+ spec.add_development_dependency 'bundler', '~> 2.3', '>= 2.3.11'
26
+ spec.add_development_dependency 'rake', '~> 12.3', '>= 12.3.3'
29
27
  spec.add_development_dependency 'rspec', '~> 3.0'
30
28
  spec.add_development_dependency 'redcarpet', '~> 3.4', '>= 3.4.0'
31
29
  spec.add_development_dependency 'simplecov', '~> 0.14.1'
@@ -111,13 +111,34 @@ module FirebaseIdToken
111
111
  # FirebaseIdToken::Certificates.request
112
112
  # cert = FirebaseIdToken::Certificates.find "1d6d01f4w7d54c7[...]"
113
113
  # #=> <OpenSSL::X509::Certificate: subject=#<OpenSSL [...]
114
- def self.find(kid)
114
+ def self.find(kid, raise_error: false)
115
115
  certs = new.local_certs
116
116
  raise Exceptions::NoCertificatesError if certs.empty?
117
117
 
118
- if certs[kid]
119
- OpenSSL::X509::Certificate.new certs[kid]
120
- end
118
+ return OpenSSL::X509::Certificate.new certs[kid] if certs[kid]
119
+
120
+ return unless raise_error
121
+
122
+ raise Exceptions::CertificateNotFound,
123
+ "Unable to find a certificate with `#{kid}`."
124
+ end
125
+
126
+ # Returns a `OpenSSL::X509::Certificate` object of the requested Key ID
127
+ # (KID) if there's one.
128
+ #
129
+ # @raise {Exceptions::CertificateNotFound} if it cannot be found.
130
+ #
131
+ # @raise {Exceptions::NoCertificatesError} if the Redis certificates
132
+ # database is empty.
133
+ #
134
+ # @param [String] kid Key ID
135
+ # @return [OpenSSL::X509::Certificate]
136
+ # @example
137
+ # FirebaseIdToken::Certificates.request
138
+ # cert = FirebaseIdToken::Certificates.find! "1d6d01f4w7d54c7[...]"
139
+ # #=> <OpenSSL::X509::Certificate: subject=#<OpenSSL [...]
140
+ def self.find!(kid)
141
+ find(kid, raise_error: true)
121
142
  end
122
143
 
123
144
  # Returns the current certificates TTL (Time-To-Live) in seconds. *Zero
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module FirebaseIdToken
4
+ module Exceptions
5
+ # @see FirebaseIdToken::Certificates.find!
6
+ class CertificateNotFound < StandardError; end
7
+ end
8
+ end
@@ -42,9 +42,25 @@ module FirebaseIdToken
42
42
  # Note that it will raise a {Exceptions::NoCertificatesError} if the Redis
43
43
  # certificates database is empty. Ensure to call {Certificates.request}
44
44
  # before, ideally in a background job if you are using Rails.
45
+ #
46
+ # If you would like this to raise and error, rather than silently failing,
47
+ # you can with the `raise_error` parameter. Example:
48
+ #
49
+ # FirebaseIdToken::Signature
50
+ # .verify(token, raise_error: Rails.env.development?)
51
+ #
52
+ # @param raise_error [Boolean] default: false
45
53
  # @return [nil, Hash]
46
- def self.verify(jwt_token)
47
- new(jwt_token).verify
54
+ def self.verify(jwt_token, raise_error: false)
55
+ new(jwt_token, raise_error: raise_error).verify
56
+ end
57
+
58
+ # Equivalent to `.verify(jwt_token, raise_error: true)`.
59
+ #
60
+ # @see {Signature.verify}
61
+ # @return [Hash]
62
+ def self.verify!(jwt_token)
63
+ new(jwt_token, raise_error: true).verify
48
64
  end
49
65
 
50
66
  attr_accessor :firebase_id_token_certificates
@@ -52,21 +68,34 @@ module FirebaseIdToken
52
68
  # Loads attributes: `:project_ids` from {FirebaseIdToken::Configuration},
53
69
  # and `:kid`, `:jwt_token` from the related `jwt_token`.
54
70
  # @param [String] jwt_token Firebase ID Token
55
- def initialize(jwt_token)
71
+ def initialize(jwt_token, raise_error: false)
72
+ @raise_error = raise_error
56
73
  @project_ids = FirebaseIdToken.configuration.project_ids
57
74
  @kid = extract_kid(jwt_token)
58
75
  @jwt_token = jwt_token
59
76
  @firebase_id_token_certificates = FirebaseIdToken.configuration.certificates
60
-
61
77
  end
62
78
 
63
79
  # @see Signature.verify
64
80
  def verify
65
- certificate = firebase_id_token_certificates.find(@kid)
66
- if certificate
67
- payload = decode_jwt_payload(@jwt_token, certificate.public_key)
68
- authorize payload
81
+ var_name = :_firebase_id_token_cert
82
+ Thread.current[var_name] ||= {
83
+ cert: nil,
84
+ expires_at: Time.now.utc - 1
85
+ }
86
+
87
+ if Thread.current[var_name][:expires_at] <= Time.now.utc
88
+ Thread.current[var_name] = {
89
+ cert: firebase_id_token_certificates.find(@kid, raise_error: @raise_error),
90
+ expires_at: Time.now.utc + firebase_id_token_certificates.ttl
91
+ }
69
92
  end
93
+
94
+ certificate = Thread.current[var_name][:cert]
95
+ return unless certificate
96
+
97
+ payload = decode_jwt_payload(@jwt_token, certificate.public_key)
98
+ authorize payload
70
99
  end
71
100
 
72
101
  private
@@ -74,13 +103,17 @@ module FirebaseIdToken
74
103
  def extract_kid(jwt_token)
75
104
  JWT.decode(jwt_token, nil, false).last['kid']
76
105
  rescue StandardError
77
- 'none'
106
+ return 'none' unless @raise_error
107
+
108
+ raise
78
109
  end
79
110
 
80
111
  def decode_jwt_payload(token, cert_key)
81
112
  JWT.decode(token, cert_key, true, JWT_DEFAULTS).first
82
113
  rescue StandardError
83
- nil
114
+ return nil unless @raise_error
115
+
116
+ raise
84
117
  end
85
118
 
86
119
  def authorize(payload)
@@ -97,8 +130,8 @@ module FirebaseIdToken
97
130
  end
98
131
 
99
132
  def still_valid?(payload)
100
- payload['exp'].to_i > Time.now.to_i &&
101
- payload['iat'].to_i <= Time.now.to_i
133
+ payload['exp'].to_i > Time.current.to_i &&
134
+ payload['iat'].to_i <= Time.current.to_i
102
135
  end
103
136
 
104
137
  def issuer_authorized?(payload)
@@ -12,10 +12,10 @@ module FirebaseIdToken
12
12
  # + {Certificates.private_key}
13
13
  # + {Certificates.certificate}
14
14
  class Certificates
15
- # `.find` is stabbed to always return the same certificate.
15
+ # `.find` is stubbed to always return the same certificate.
16
16
  # @param [String] kid Key ID
17
17
  # @return [nil, OpenSSL::X509::Certificate]
18
- def self.find(kid)
18
+ def self.find(kid, raise_error: false)
19
19
  cert = certificate
20
20
  OpenSSL::X509::Certificate.new cert
21
21
  end
@@ -80,6 +80,10 @@ module FirebaseIdToken
80
80
  )
81
81
  )
82
82
  end
83
+
84
+ def self.ttl
85
+ 10
86
+ end
83
87
  end
84
88
  end
85
89
  end
@@ -1,3 +1,3 @@
1
1
  module FirebaseIdToken
2
- VERSION = '2.3.1'
2
+ VERSION = '2.5.0'
3
3
  end
@@ -7,6 +7,7 @@ require 'firebase_id_token/version'
7
7
  require 'firebase_id_token/exceptions/no_certificates_error'
8
8
  require 'firebase_id_token/exceptions/certificates_request_error'
9
9
  require 'firebase_id_token/exceptions/certificates_ttl_error'
10
+ require 'firebase_id_token/exceptions/certificate_not_found'
10
11
  require 'firebase_id_token/configuration'
11
12
  require 'firebase_id_token/certificates'
12
13
  require 'firebase_id_token/signature'
@@ -49,7 +50,7 @@ module FirebaseIdToken
49
50
 
50
51
  def self.configuration
51
52
  @configuration ||= Configuration.new
52
- end
53
+ end
53
54
 
54
55
  # Resets Configuration to defaults.
55
56
  def self.reset
@@ -0,0 +1,164 @@
1
+ require 'spec_helper'
2
+
3
+ module FirebaseIdToken
4
+ describe Certificates do
5
+ let (:redis) { Redis::Namespace.new 'firebase_id_token', redis: Redis.new }
6
+ let (:certs) { File.read('spec/fixtures/files/certificates.json') }
7
+ let (:cache) { 'public, max-age=19302, must-revalidate, no-transform' }
8
+ let (:low_cache) { 'public, max-age=2160, must-revalidate, no-transform' }
9
+ let (:kid) { JSON.parse(certs).first[0] }
10
+ let (:expires_in) { (DateTime.now + (5/24r)).to_s }
11
+ let (:response) { double }
12
+
13
+ let (:mock_response) {
14
+ allow(response).to receive(:code) { 200 }
15
+ allow(response).to receive(:headers) { { 'cache-control' => cache } }
16
+ allow(response).to receive(:body) { certs }
17
+ }
18
+
19
+ let(:mock_request) {
20
+ mock_response
21
+ allow(HTTParty).to receive(:get).
22
+ with(an_instance_of(String)) { response }
23
+ }
24
+
25
+ before :each do
26
+ redis.del 'certificates'
27
+ mock_request
28
+ end
29
+
30
+ describe '#request' do
31
+ it 'requests certificates when Redis database is empty' do
32
+ expect(HTTParty).to receive(:get).
33
+ with(FirebaseIdToken::Certificates::URL)
34
+ described_class.request
35
+ end
36
+
37
+ it 'does not requests certificates when Redis database is written' do
38
+ expect(HTTParty).to receive(:get).
39
+ with(FirebaseIdToken::Certificates::URL).once
40
+ 2.times { described_class.request }
41
+ end
42
+ end
43
+
44
+ describe '#request!' do
45
+ it 'always requests certificates' do
46
+ expect(HTTParty).to receive(:get).
47
+ with(FirebaseIdToken::Certificates::URL).twice
48
+ 2.times { described_class.request! }
49
+ end
50
+
51
+ it 'sets the certificate expiration time as Redis TTL' do
52
+ described_class.request!
53
+ expect(redis.ttl('certificates')).to be > 3600
54
+ end
55
+
56
+ it 'raises a error when certificates expires in less than 1 hour' do
57
+ allow(response).to receive(:headers) {{'cache-control' => low_cache}}
58
+ expect{ described_class.request! }.
59
+ to raise_error(Exceptions::CertificatesTtlError)
60
+ end
61
+
62
+ it 'raises a error when HTTP response code is other than 200' do
63
+ allow(response).to receive(:code) { 401 }
64
+ expect{ described_class.request! }.
65
+ to raise_error(Exceptions::CertificatesRequestError)
66
+ end
67
+ end
68
+
69
+ describe '#request_anyway' do
70
+ it 'also requests certificates' do
71
+ expect(HTTParty).to receive(:get).
72
+ with(FirebaseIdToken::Certificates::URL)
73
+
74
+ described_class.request_anyway
75
+ end
76
+ end
77
+
78
+ describe '.present?' do
79
+ it 'returns false when Redis database is empty' do
80
+ expect(described_class.present?).to be(false)
81
+ end
82
+
83
+ it 'returns true when Redis database is written' do
84
+ described_class.request
85
+ expect(described_class.present?).to be(true)
86
+ end
87
+ end
88
+
89
+ describe '.all' do
90
+ context 'before requesting certificates' do
91
+ it 'returns a empty Array' do
92
+ expect(described_class.all).to eq([])
93
+ end
94
+ end
95
+
96
+ context 'after requesting certificates' do
97
+ it 'returns a array of hashes: String keys' do
98
+ described_class.request
99
+ expect(described_class.all.first.keys[0]).to be_a(String)
100
+ end
101
+
102
+ it 'returns a array of hashes: OpenSSL::X509::Certificate values' do
103
+ described_class.request
104
+ expect(described_class.all.first.values[0]).
105
+ to be_a(OpenSSL::X509::Certificate)
106
+ end
107
+ end
108
+ end
109
+
110
+ describe '.find' do
111
+ context 'without certificates in Redis database' do
112
+ it 'raises a exception' do
113
+ expect{ described_class.find(kid)}.
114
+ to raise_error(Exceptions::NoCertificatesError)
115
+ end
116
+ end
117
+
118
+ context 'with certificates in Redis database' do
119
+ it 'returns a OpenSSL::X509::Certificate when it finds the kid' do
120
+ described_class.request
121
+ expect(described_class.find(kid)).to be_a(OpenSSL::X509::Certificate)
122
+ end
123
+
124
+ it 'returns nil when it can not find the kid' do
125
+ described_class.request
126
+ expect(described_class.find('')).to be(nil)
127
+ end
128
+ end
129
+ end
130
+
131
+ describe '.find!' do
132
+ context 'without certificates in Redis database' do
133
+ it 'raises a exception' do
134
+ expect{ described_class.find!(kid)}.
135
+ to raise_error(Exceptions::NoCertificatesError)
136
+ end
137
+ end
138
+ context 'with certificates in Redis database' do
139
+ it 'returns a OpenSSL::X509::Certificate when it finds the kid' do
140
+ described_class.request
141
+ expect(described_class.find!(kid)).to be_a(OpenSSL::X509::Certificate)
142
+ end
143
+
144
+ it 'raises a CertificateNotFound error when it can not find the kid' do
145
+ described_class.request
146
+ expect { described_class.find!('') }
147
+ .to raise_error(Exceptions::CertificateNotFound, /Unable to find/)
148
+ end
149
+ end
150
+
151
+ end
152
+
153
+ describe '.ttl' do
154
+ it 'returns a positive number when has certificates in Redis' do
155
+ described_class.request
156
+ expect(described_class.ttl).to be > 0
157
+ end
158
+
159
+ it 'returns zero when has no certificates in Redis' do
160
+ expect(described_class.ttl).to eq(0)
161
+ end
162
+ end
163
+ end
164
+ end
@@ -0,0 +1,33 @@
1
+ require 'spec_helper'
2
+
3
+ module FirebaseIdToken
4
+ describe Configuration do
5
+ describe '.project_ids' do
6
+ it 'sets [] as default' do
7
+ expect(Configuration.new.project_ids).to eq([])
8
+ end
9
+ end
10
+
11
+ describe '.project_ids=' do
12
+ it 'changes default values' do
13
+ config = Configuration.new
14
+ config.project_ids = String.new
15
+ expect(config.project_ids).to be_a(String)
16
+ end
17
+ end
18
+
19
+ describe '.redis' do
20
+ it 'sets a Redis instance as default' do
21
+ expect(Configuration.new.redis).to be_a(Redis)
22
+ end
23
+ end
24
+
25
+ describe '.redis=' do
26
+ it 'changes default values' do
27
+ config = Configuration.new
28
+ config.redis = String.new
29
+ expect(config.redis).to be_a(String)
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,53 @@
1
+ require 'spec_helper'
2
+
3
+ module FirebaseIdToken
4
+ describe Signature do
5
+ let(:jwt) { JSON.parse File.read('spec/fixtures/files/jwt.json') }
6
+ let(:raise_certificates_error) { false }
7
+
8
+ let(:mock_certificates) do
9
+ allow(Certificates)
10
+ .to(receive(:find))
11
+ .with(an_instance_of(String), raise_error: raise_certificates_error)
12
+ .and_return(OpenSSL::X509::Certificate.new(jwt['certificate']))
13
+ end
14
+
15
+ before :each do
16
+ mock_certificates
17
+ FirebaseIdToken.configure do |config|
18
+ config.project_ids = ['firebase-id-token']
19
+ end
20
+ end
21
+
22
+ describe '#verify' do
23
+ it 'returns a Hash when the signature is valid' do
24
+ expect(described_class.verify(jwt['jwt_token'])).to be_a(Hash)
25
+ end
26
+
27
+ it 'returns nil when the signature is invalid' do
28
+ expect(described_class.verify(jwt['bad_jwt_token'])).to be(nil)
29
+ end
30
+
31
+ it 'returns nil with a invalid key format' do
32
+ expect(described_class.verify('aaa')).to be(nil)
33
+ end
34
+ end
35
+
36
+ describe '#verify!' do
37
+ let(:raise_certificates_error) { true }
38
+ it 'returns a Hash when the signature is valid' do
39
+ expect(described_class.verify!(jwt['jwt_token'])).to be_a(Hash)
40
+ end
41
+
42
+ it 'raises an error when the signature is invalid' do
43
+ expect { described_class.verify!(jwt['bad_jwt_token']) }
44
+ .to raise_error(JWT::VerificationError)
45
+ end
46
+
47
+ it 'raises an error with a invalid key format' do
48
+ expect { described_class.verify!('aaa') }
49
+ .to raise_error(JWT::DecodeError, /too many/)
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,28 @@
1
+ require 'spec_helper'
2
+
3
+ module FirebaseIdToken
4
+ describe Signature do
5
+ let(:jwt) { JSON.parse File.read('spec/fixtures/files/jwt.json') }
6
+ let(:payload) { JSON.parse File.read('spec/fixtures/files/payload.json') }
7
+ let(:rsa_private) { OpenSSL::PKey::RSA.new(FirebaseIdToken::Testing::Certificates.private_key) }
8
+
9
+ before :each do
10
+ FirebaseIdToken.configure do |config|
11
+ config.project_ids = ['firebase-id-token']
12
+ end
13
+ FirebaseIdToken.test!
14
+ end
15
+
16
+ describe '#verify' do
17
+
18
+ it 'test mode is valid' do
19
+ expect(described_class.verify(jwt['jwt_token'])).to be_a(Hash)
20
+ end
21
+
22
+ it 'test mode encode is valid' do
23
+ JWT.encode payload, rsa_private, 'RS256'
24
+ expect(described_class.verify(jwt['jwt_token'])).to be_a(Hash)
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,46 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe FirebaseIdToken do
4
+ let(:jwt) { JSON.parse File.read('spec/fixtures/files/jwt.json') }
5
+
6
+ let (:mock_certificates) {
7
+ allow(FirebaseIdToken::Certificates).to receive(:find).
8
+ with(an_instance_of(String)) {
9
+ OpenSSL::X509::Certificate.new(jwt['certificate']) }
10
+ }
11
+
12
+ it 'has a version number' do
13
+ expect(FirebaseIdToken::VERSION).not_to be nil
14
+ end
15
+
16
+ describe '#configure' do
17
+ before :each do
18
+ mock_certificates
19
+ FirebaseIdToken.configure do |config|
20
+ config.project_ids = ['firebase-id-token']
21
+ end
22
+ end
23
+
24
+ it 'sets global project_ids' do
25
+ expect(FirebaseIdToken::Signature.verify(jwt['jwt_token'])).to be_a(Hash)
26
+ end
27
+
28
+ after :each do
29
+ FirebaseIdToken.reset
30
+ end
31
+ end
32
+
33
+ describe '#reset' do
34
+ before :each do
35
+ FirebaseIdToken.configure do |config|
36
+ config.project_ids = 1
37
+ end
38
+ end
39
+
40
+ it 'resets the configuration' do
41
+ FirebaseIdToken.reset
42
+ config = FirebaseIdToken.configuration
43
+ expect(config.project_ids).to eq([])
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,3 @@
1
+ About the payload.json
2
+
3
+ Keep it for didactic and debugging reasons.
@@ -0,0 +1,5 @@
1
+ {
2
+ "1d6d911c0c01c7871befbedab6fe4aa932cb14b1":"-----BEGIN CERTIFICATE-----\nMIIDHDCCAgSgAwIBAgIIcM5ipUjH60gwDQYJKoZIhvcNAQEFBQAwMTEvMC0GA1UE\nAxMmc2VjdXJldG9rZW4uc3lzdGVtLmdzZXJ2aWNlYWNjb3VudC5jb20wHhcNMTcw\nNDIwMDA0NTI2WhcNMTcwNDIzMDExNTI2WjAxMS8wLQYDVQQDEyZzZWN1cmV0b2tl\nbi5zeXN0ZW0uZ3NlcnZpY2VhY2NvdW50LmNvbTCCASIwDQYJKoZIhvcNAQEBBQAD\nggEPADCCAQoCggEBAL1PdoFtJ6YI+TLRPZcNNElRlOHmGGvBvilmgZEa3Pn5P6BH\n7NIi1PuLlRKoAOh+m+NBxEP+o6X6SVyLxhmLqoUmNxJP1UzdP4iUV4taSe5Ar6LG\nuPFwzzFTygHVZmiED+0/YhaigcPWakU29rDKBBzi3mbHOrftCENc4MjSj+VgN0f7\namTXEHvs/mnCaKs9llIKLFNkxZMCLYYUI8z/fAswkvF+16jr1hWMQhJ0EtsrS7+s\nAaDainDxRHQdL/C3invOp/+MdtV9JD76uTcwRaJnevtMAwReGsuVuQ9ytueFMjDR\ndwAcXEj7DFum7UlG4YUJNyrwfFMP7STdXMDIcU0CAwEAAaM4MDYwDAYDVR0TAQH/\nBAIwADAOBgNVHQ8BAf8EBAMCB4AwFgYDVR0lAQH/BAwwCgYIKwYBBQUHAwIwDQYJ\nKoZIhvcNAQEFBQADggEBACUU6SbF+W/PIQLu4JKc2AuyqFG3+HMHTggq6lFDoe4h\nrdOFf1GwGBir5QLRp4VteYMpHuluZ30l+83XfPW82Bi3Xg+oXCs/ZdlwOSYB60R1\nJHLh2fnjquydwTDnHvfiGKPbE+/BgIbW7CfKRjdZxOTx/kbyymhriT2vBSf9nePF\nH9qEtcs/Y95PEdt28Jrjcn4r9tqnNb9w3J6bN0VGndegvwtrPzacyXXsawOny0Ij\n/1I7CJ19bYFQ9dPjvQzUUssUbSmCfl0p+s+6FzzWbaZxcOga2NoqESU522s1VVyx\niKFq8KyT6RD1RKr3vQwULR7h5HU0pkPJz3UCLpy6udw=\n-----END CERTIFICATE-----\n",
3
+ "1dd4bb29a77e0d8f3ddcb6af82444bee2e1f8f41":"-----BEGIN CERTIFICATE-----\nMIIDHDCCAgSgAwIBAgIIff9h3dvZ7S0wDQYJKoZIhvcNAQEFBQAwMTEvMC0GA1UE\nAxMmc2VjdXJldG9rZW4uc3lzdGVtLmdzZXJ2aWNlYWNjb3VudC5jb20wHhcNMTcw\nNDIxMDA0NTI2WhcNMTcwNDI0MDExNTI2WjAxMS8wLQYDVQQDEyZzZWN1cmV0b2tl\nbi5zeXN0ZW0uZ3NlcnZpY2VhY2NvdW50LmNvbTCCASIwDQYJKoZIhvcNAQEBBQAD\nggEPADCCAQoCggEBAOkr+xUfSLz88cuxUEodF9YPLQDjIU/6EOIpkOmI8hLbEgPL\nXtWdudzWlZ231Owy6bhywc+WZLgDnAdAU0RCoy0kZkiAShU5qGWMLp59gC9VCS/Y\nPsw6N8VJM6G4Qekjdy/X/0QRSi26RdIbdlKuN+NF4gN0feRk8gXxfeCYzF2FxN8q\nyH8uIwpchHd0rix0sKjXxE3K/4Sw+NxNIcdVyYuu6qvCs0L+vRT7AYBWPOveTPSj\nnbf8hTAx/Le2hDJZ/aARe7lZNGGqgrJweXT9XB6SEG0mzh/9ShaA22Tlsrhb/1K/\n1xMDdCdS/6cCcHhEVw1tsZHN9GpyfQQAdYjXvncCAwEAAaM4MDYwDAYDVR0TAQH/\nBAIwADAOBgNVHQ8BAf8EBAMCB4AwFgYDVR0lAQH/BAwwCgYIKwYBBQUHAwIwDQYJ\nKoZIhvcNAQEFBQADggEBAHpCWcikPhudhZ4ZfO+Y52CD6N50w+dse0X5lNKK9D7g\nC/6At8KY74NAD4wiCv6l3f6Eyq0kIlOwjHykzmTgrwcY3GI9FauCPkzl1pzfw5Cr\n6kuePTjMd67vi3XanQ2ZhM0g/CUQHR8VYELwMhh8dPaI/enmq7Yw7UAUKxDmI4zD\nz8VTb/A2LA+HgIk+X9lRW5fSHCm2ujN8VzYUr/BKx6U58x/qVp1Y1J0mXJdrmyK6\ngPb4Ro0/zPscMbeKNqNbTeCT5YXTNtU9+Zzs3OJ+e283EyR3h0VfdqD266kr0yuy\njq/v/Rplwrf8fHGEkdVTApWUb1nSbK0obLzkqb3ut9Q=\n-----END CERTIFICATE-----\n",
4
+ "e2e353f4bd0fd6189e532c2377771439d903c346":"-----BEGIN CERTIFICATE-----\nMIIDHDCCAgSgAwIBAgIIFqTX4DUSi0gwDQYJKoZIhvcNAQEFBQAwMTEvMC0GA1UE\nAxMmc2VjdXJldG9rZW4uc3lzdGVtLmdzZXJ2aWNlYWNjb3VudC5jb20wHhcNMTcw\nNDE5MDA0NTI2WhcNMTcwNDIyMDExNTI2WjAxMS8wLQYDVQQDEyZzZWN1cmV0b2tl\nbi5zeXN0ZW0uZ3NlcnZpY2VhY2NvdW50LmNvbTCCASIwDQYJKoZIhvcNAQEBBQAD\nggEPADCCAQoCggEBAKxLXZ0dYY5SRXyG2FiiEUXUb2qEX5u6svjiexIEuvO/9eP2\n4B/dkICJLI7RfQcogtkn5SCi7Cd/szuLT5z1AeGQdqgU7OBVgMGyzG4bf03DNqfh\noRghroG+mIrvE/4Qx2x2reokc0ShlrBBpZUh/EU89NAvJkudp0MqtoGNhzH6CQ5X\nmUXThpu7RVb7ciHrW1HRlMZjCNcLDkUEm4FPGtBT1T2zvCOLjrOG9BmhX97PtV2l\nFrbzIG0Z0nYa3y+hIyNfVwC+CjqNRHYdmDDt3fEM7B9IlS9wpd6waphxY6j09VNy\nCQtKuRhenReiY2uM8sRfZvqNH+guOkb2NZ77hW8CAwEAAaM4MDYwDAYDVR0TAQH/\nBAIwADAOBgNVHQ8BAf8EBAMCB4AwFgYDVR0lAQH/BAwwCgYIKwYBBQUHAwIwDQYJ\nKoZIhvcNAQEFBQADggEBADUioofGGbdCcSZdgVruwmpMl3FYWu+c5OknBiLyQmtj\nH7okp0DXXq0k+JXe3Q5b8AoOQnDbS0drETGB9Bi145/cv3KfF9cHw+OLF1/sOLDD\n23FvvZWYjWngOIG7tNeMUprb981lc4xUrW8ViqtbPUqJNO5dEPU1MHPm7oxTavH9\nm7nPT7xzI5TuaQnQ0Dql8nlirJOCu2DO47ug4+J5C6fsHPW3c4Ui2VdLtNGDHm2L\nQCAOfti8SukoHF9z1NnHX4ODkEHtALoDN/XygMabgLBuuZneCJShEYsNNtN3Tl0G\nyKRpTYkiDzegpVgehCjQK3EYM2io0uxDgVb+9fT2WpA=\n-----END CERTIFICATE-----\n"
5
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "private_key": "-----BEGIN RSA PRIVATE KEY-----\nMIICXAIBAAKBgQCrvJRW05yKQxx3+PdiysRKR/N+VqYv9+b/76C3zC/vk9ACkWTN\n/dcPMzIXVIdDMU+r1o8HF3mOXNhCFWGSfZ7r1dMe961BQtxu1DagC7Ff+XZZL0Mu\n0W0Y/GmP7yTrsie7wCq4QiHj2HBtUtze/uC6DT8Qcthg46LUJBqeh9FiIwIDAQAB\nAoGAEGK80I/+Np7yn2vMxstL8T5uOBayYo9HphHKBt9fj39N8IDI2nKmy1d6Jwm0\noi+ZR28AVI/j1DZ9l8iMd7qup+/D5CdTt89u8fTUlQkCjAQQsRBneq5MJRKI+5eA\nJDJmx7p7CUUqjnIcFfbBz0NLTDZso11Vp+BDfbDpKv37nskCQQDZimWuxa7rK6UZ\nXGDl8LxEiM27US67kDu8iS3VdQWEKIhhQoea/zNKPMkQsc2+CPggQTcG/2WuPEYJ\nO1bPz7HPAkEAyhknhziWREEBQRLp4qsakozMIn4iuuaC00zpLwcnyOqFPaHS5CTL\nI7GxpwN6Ld1N/nqvYGyk/dRb5Ul7v27DbQJAUMsJwMNCl6z6AFVC16N1CK8WWX9p\nL9f9l6QLFcAEcHTtUdH3syUc03GH619d3jpOjQwrd7na9b8E8+DJ+RxWGQJAI8cE\nOmoIIBkp8a05fokv8RW/5bNSzqeULXgGJ+8qWeU6pUiKnxzsYWtJuflhndD5x71M\nYtOY+d6oThUONTuUmQJBAMGl/eaFU0AfA+xS/3Kt5JFKBbBVAByhL+Hd/27/rYZ5\n8YXDUQAgcykCS21JMrn41p4gwJnpG35PoV8qBIW9a94=\n-----END RSA PRIVATE KEY-----",
3
+ "certificate": "-----BEGIN CERTIFICATE-----\nMIIChDCCAe2gAwIBAgIBADANBgkqhkiG9w0BAQUFADA6MQswCQYDVQQGEwJCRTEN\nMAsGA1UECgwEVGVzdDENMAsGA1UECwwEVGVzdDENMAsGA1UEAwwEVGVzdDAgFw0x\nNzA0MjQwMjE5MzRaGA8zMDE2MDgyNTAyMTkzNFowOjELMAkGA1UEBhMCQkUxDTAL\nBgNVBAoMBFRlc3QxDTALBgNVBAsMBFRlc3QxDTALBgNVBAMMBFRlc3QwgZ8wDQYJ\nKoZIhvcNAQEBBQADgY0AMIGJAoGBAKu8lFbTnIpDHHf492LKxEpH835Wpi/35v/v\noLfML++T0AKRZM391w8zMhdUh0MxT6vWjwcXeY5c2EIVYZJ9nuvV0x73rUFC3G7U\nNqALsV/5dlkvQy7RbRj8aY/vJOuyJ7vAKrhCIePYcG1S3N7+4LoNPxBy2GDjotQk\nGp6H0WIjAgMBAAGjgZcwgZQwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUFKl2\nnZaaeNZM/7dno9IbaEIvaXQwYgYDVR0jBFswWYAUFKl2nZaaeNZM/7dno9IbaEIv\naXShPqQ8MDoxCzAJBgNVBAYTAkJFMQ0wCwYDVQQKDARUZXN0MQ0wCwYDVQQLDARU\nZXN0MQ0wCwYDVQQDDARUZXN0ggEAMA0GCSqGSIb3DQEBBQUAA4GBAKkBvhUIRENB\nap0r9F7sKkRr8tJCCjBPIA+8e8XIKS3A3w6EI5ErRpv795rO80TBR4WZR9GhH8M1\nPXJ7FuaayCcPAl0febjl4z6ZciCSDpBdhbMpmq1d/kYU1H1qUokE2BxhNdcs/Q4w\n+5NnFGSkYm09tPzLWFPLoES9ynBF0N7l\n-----END CERTIFICATE-----",
4
+ "jwt_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6IjEyM3F3ZSJ9.eyJpc3MiOiJodHRwczovL3NlY3VyZXRva2VuLmdvb2dsZS5jb20vZmlyZWJhc2UtaWQtdG9rZW4iLCJuYW1lIjoiVWdseSBCb2IiLCJwaWN0dXJlIjoiaHR0cHM6Ly9zb21ldXJsLmNvbS9waG90by5qcGciLCJhdWQiOiJmaXJlYmFzZS1pZC10b2tlbiIsImF1dGhfdGltZSI6MTQ5Mjk4MTE5MiwidXNlcl9pZCI6InRoZVVzZXJJRCIsInN1YiI6InRoZVVzZXJJRCIsImlhdCI6MTQ5Mjk4MTIwMCwiZXhwIjozMzAyOTAwMDAxNywiZW1haWwiOiJ1Z2x5Ym9iQGVtYWlsdXJsLmNvbSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJmaXJlYmFzZSI6eyJpZGVudGl0aWVzIjp7Imdvb2dsZS5jb20iOlsiMTAxMDEwMTAxMDEwMTAxMDEwMSJdLCJlbWFpbCI6WyJ1Z2x5Ym9iQGVtYWlsdXJsLmNvbSJdfSwic2lnbl9pbl9wcm92aWRlciI6Imdvb2dsZS5jb20ifX0.PjTLVli92r41PfptLsmfeKG-ThEj7SNM02yx8YSVf_b-DiYBqgDJrrFgUP29oy86K8v6bRzirgyq3fmxzBj9YIlhnOar_8QlEwr8U-m-85wcP3kDQmXE2QQRF8MQPMOVyPjn2skKNS3Wu1zZYoMT0dqygh2qxqvbouCGjum0REg",
5
+ "bad_jwt_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6IjEyM3F3ZSJ9.eyJpc3MiOiJodHRwczovL3NlY3VyZXRva2VuLmdvb2dsZS5jb20vZmlyZWJhc2UtaWQtdG9rZW4iLCJuYW1lIjoiVWdseSBCb2IiLCJwaWN0dXJlIjoiaHR0cHM6Ly9zb21ldXJsLmNvbS9waG90by5qcGciLCJhdWQiOiJmaXJlYmFzZS1pZC10b2tlbiIsImF1dGhfdGltZSI6MTQ5Mjk4MTE5MiwidXNlcl9pZCI6InRoZVVzZXJJRCIsInN1YiI6InRoZVVzZXJJRCIsImlhdCI6MTQ5Mjk4MTIwMCwiZXhwIjozMzAyOTAwMDAxNywiZW1haWwiOiJ1Z2x5Ym9iQGVtYWlsdXJsLmNvbSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJmaXJlYmFzZSI6eyJpZGVudGl0aWVzIjp7Imdvb2dsZS5jb20iOlsiMTAxMDEwMTAxMDEwMTAxMDEwMSJdLCJlbWFpbCI6WyJ1Z2x5Ym9iQGVtYWlsdXJsLmNvbSJdfSwic2lnbl9pbl9wcm92aWRlciI6Imdvb2dsZS5jb20ifX0.rR9237-LJAgdt6ICqR7qoB5625tsat8uGTszB55rSEBEop8WFvXQo0maEfwtl_3JTxUfefDkLWUaBnFqArEMPoT9TIRuBOdJtVRDSxfNjio87DumsXPb97ALX2bTUU49fwDHGBiZqkBq9m0V49O-50MfyQqS0otC2p4_pRisS4o"
6
+ }
@@ -0,0 +1,24 @@
1
+ {
2
+ "iss":"https://securetoken.google.com/firebase-id-token",
3
+ "name":"Ugly Bob",
4
+ "picture":"https://someurl.com/photo.jpg",
5
+ "aud":"firebase-id-token",
6
+ "auth_time":1492981192,
7
+ "user_id":"theUserID",
8
+ "sub":"theUserID",
9
+ "iat":1492981200,
10
+ "exp":33029000017,
11
+ "email":"uglybob@emailurl.com",
12
+ "email_verified":true,
13
+ "firebase":{
14
+ "identities":{
15
+ "google.com":[
16
+ "1010101010101010101"
17
+ ],
18
+ "email":[
19
+ "uglybob@emailurl.com"
20
+ ]
21
+ },
22
+ "sign_in_provider":"google.com"
23
+ }
24
+ }
@@ -0,0 +1,19 @@
1
+ require 'simplecov'
2
+ SimpleCov.start
3
+
4
+ require 'bundler/setup'
5
+ require 'redis'
6
+ require 'redis-namespace'
7
+ require 'httparty'
8
+ require 'jwt'
9
+ require 'firebase_id_token'
10
+ require 'pry'
11
+
12
+ RSpec.configure do |config|
13
+ # Enable flags like --only-failures and --next-failure
14
+ config.example_status_persistence_file_path = '.rspec_status'
15
+
16
+ config.expect_with :rspec do |c|
17
+ c.syntax = :expect
18
+ end
19
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: firebase_id_token
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.3.1
4
+ version: 2.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Fernando Schuindt
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-08-13 00:00:00.000000000 Z
11
+ date: 2022-04-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -16,28 +16,40 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.14'
19
+ version: '2.3'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 2.3.11
20
23
  type: :development
21
24
  prerelease: false
22
25
  version_requirements: !ruby/object:Gem::Requirement
23
26
  requirements:
24
27
  - - "~>"
25
28
  - !ruby/object:Gem::Version
26
- version: '1.14'
29
+ version: '2.3'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 2.3.11
27
33
  - !ruby/object:Gem::Dependency
28
34
  name: rake
29
35
  requirement: !ruby/object:Gem::Requirement
30
36
  requirements:
31
37
  - - "~>"
32
38
  - !ruby/object:Gem::Version
33
- version: '10.0'
39
+ version: '12.3'
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: 12.3.3
34
43
  type: :development
35
44
  prerelease: false
36
45
  version_requirements: !ruby/object:Gem::Requirement
37
46
  requirements:
38
47
  - - "~>"
39
48
  - !ruby/object:Gem::Version
40
- version: '10.0'
49
+ version: '12.3'
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: 12.3.3
41
53
  - !ruby/object:Gem::Dependency
42
54
  name: rspec
43
55
  requirement: !ruby/object:Gem::Requirement
@@ -56,22 +68,22 @@ dependencies:
56
68
  name: redcarpet
57
69
  requirement: !ruby/object:Gem::Requirement
58
70
  requirements:
59
- - - ">="
60
- - !ruby/object:Gem::Version
61
- version: 3.4.0
62
71
  - - "~>"
63
72
  - !ruby/object:Gem::Version
64
73
  version: '3.4'
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: 3.4.0
65
77
  type: :development
66
78
  prerelease: false
67
79
  version_requirements: !ruby/object:Gem::Requirement
68
80
  requirements:
69
- - - ">="
70
- - !ruby/object:Gem::Version
71
- version: 3.4.0
72
81
  - - "~>"
73
82
  - !ruby/object:Gem::Version
74
83
  version: '3.4'
84
+ - - ">="
85
+ - !ruby/object:Gem::Version
86
+ version: 3.4.0
75
87
  - !ruby/object:Gem::Dependency
76
88
  name: simplecov
77
89
  requirement: !ruby/object:Gem::Requirement
@@ -90,22 +102,22 @@ dependencies:
90
102
  name: codeclimate-test-reporter
91
103
  requirement: !ruby/object:Gem::Requirement
92
104
  requirements:
93
- - - ">="
94
- - !ruby/object:Gem::Version
95
- version: 1.0.0
96
105
  - - "~>"
97
106
  - !ruby/object:Gem::Version
98
107
  version: '1.0'
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: 1.0.0
99
111
  type: :development
100
112
  prerelease: false
101
113
  version_requirements: !ruby/object:Gem::Requirement
102
114
  requirements:
103
- - - ">="
104
- - !ruby/object:Gem::Version
105
- version: 1.0.0
106
115
  - - "~>"
107
116
  - !ruby/object:Gem::Version
108
117
  version: '1.0'
118
+ - - ">="
119
+ - !ruby/object:Gem::Version
120
+ version: 1.0.0
109
121
  - !ruby/object:Gem::Dependency
110
122
  name: pry
111
123
  requirement: !ruby/object:Gem::Requirement
@@ -144,22 +156,22 @@ dependencies:
144
156
  name: redis-namespace
145
157
  requirement: !ruby/object:Gem::Requirement
146
158
  requirements:
147
- - - ">="
148
- - !ruby/object:Gem::Version
149
- version: 1.6.0
150
159
  - - "~>"
151
160
  - !ruby/object:Gem::Version
152
161
  version: '1.6'
162
+ - - ">="
163
+ - !ruby/object:Gem::Version
164
+ version: 1.6.0
153
165
  type: :runtime
154
166
  prerelease: false
155
167
  version_requirements: !ruby/object:Gem::Requirement
156
168
  requirements:
157
- - - ">="
158
- - !ruby/object:Gem::Version
159
- version: 1.6.0
160
169
  - - "~>"
161
170
  - !ruby/object:Gem::Version
162
171
  version: '1.6'
172
+ - - ">="
173
+ - !ruby/object:Gem::Version
174
+ version: 1.6.0
163
175
  - !ruby/object:Gem::Dependency
164
176
  name: httparty
165
177
  requirement: !ruby/object:Gem::Requirement
@@ -184,22 +196,22 @@ dependencies:
184
196
  name: jwt
185
197
  requirement: !ruby/object:Gem::Requirement
186
198
  requirements:
187
- - - ">="
188
- - !ruby/object:Gem::Version
189
- version: 2.1.0
190
199
  - - "~>"
191
200
  - !ruby/object:Gem::Version
192
201
  version: '2.1'
202
+ - - ">="
203
+ - !ruby/object:Gem::Version
204
+ version: 2.1.0
193
205
  type: :runtime
194
206
  prerelease: false
195
207
  version_requirements: !ruby/object:Gem::Requirement
196
208
  requirements:
197
- - - ">="
198
- - !ruby/object:Gem::Version
199
- version: 2.1.0
200
209
  - - "~>"
201
210
  - !ruby/object:Gem::Version
202
211
  version: '2.1'
212
+ - - ">="
213
+ - !ruby/object:Gem::Version
214
+ version: 2.1.0
203
215
  description: A Ruby gem to verify the signature of Firebase ID Tokens. It uses Redis
204
216
  to store Google's x509 certificates and manage their expiration time, so you don't
205
217
  need to request Google's API in every execution and can access it as fast as reading
@@ -214,6 +226,7 @@ files:
214
226
  - ".rspec"
215
227
  - ".travis.yml"
216
228
  - ".yardopts"
229
+ - CHANGELOG.md
217
230
  - CODE_OF_CONDUCT.md
218
231
  - Gemfile
219
232
  - LICENSE.txt
@@ -221,21 +234,33 @@ files:
221
234
  - Rakefile
222
235
  - bin/console
223
236
  - bin/setup
237
+ - docker-compose.yml
224
238
  - firebase_id_token.gemspec
225
239
  - lib/firebase_id_token.rb
226
240
  - lib/firebase_id_token/certificates.rb
227
241
  - lib/firebase_id_token/configuration.rb
242
+ - lib/firebase_id_token/exceptions/certificate_not_found.rb
228
243
  - lib/firebase_id_token/exceptions/certificates_request_error.rb
229
244
  - lib/firebase_id_token/exceptions/certificates_ttl_error.rb
230
245
  - lib/firebase_id_token/exceptions/no_certificates_error.rb
231
246
  - lib/firebase_id_token/signature.rb
232
247
  - lib/firebase_id_token/testing/certificates.rb
233
248
  - lib/firebase_id_token/version.rb
249
+ - spec/firebase_id_token/certificates_spec.rb
250
+ - spec/firebase_id_token/configuration_spec.rb
251
+ - spec/firebase_id_token/signature_spec.rb
252
+ - spec/firebase_id_token/signature_test_spec.rb
253
+ - spec/firebase_id_token_spec.rb
254
+ - spec/fixtures/files/.about_payload_file
255
+ - spec/fixtures/files/certificates.json
256
+ - spec/fixtures/files/jwt.json
257
+ - spec/fixtures/files/payload.json
258
+ - spec/spec_helper.rb
234
259
  homepage: https://github.com/fschuindt/firebase_id_token
235
260
  licenses:
236
261
  - MIT
237
262
  metadata: {}
238
- post_install_message:
263
+ post_install_message:
239
264
  rdoc_options: []
240
265
  require_paths:
241
266
  - lib
@@ -250,8 +275,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
250
275
  - !ruby/object:Gem::Version
251
276
  version: '0'
252
277
  requirements: []
253
- rubygems_version: 3.0.3
254
- signing_key:
278
+ rubygems_version: 3.1.4
279
+ signing_key:
255
280
  specification_version: 4
256
281
  summary: A Firebase ID Token verifier.
257
282
  test_files: []