firejwt 0.1.2 → 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/go.sum CHANGED
@@ -1,43 +1,6 @@
1
- github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
2
- github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
3
- github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
4
- github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
5
- github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
6
- github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
7
- github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
8
- github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
9
- github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
10
- github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
11
- github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
12
- github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
13
- github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
14
- github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
15
- github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
16
- github.com/onsi/ginkgo v1.11.0 h1:JAKSXpt1YjtLA7YpPiqO9ss6sNXEsPfSGdwN0UHqzrw=
17
- github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
18
- github.com/onsi/gomega v1.8.1 h1:C5Dqfs/LeauYDX0jJXIe2SWmwCbGzx9yF8C8xy3Lh34=
19
- github.com/onsi/gomega v1.8.1/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA=
20
- golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
21
- golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
22
- golang.org/x/net v0.0.0-20191007182048-72f939374954 h1:JGZucVF/L/TotR719NbujzadOZ2AgnYlqphQGHDCKaU=
23
- golang.org/x/net v0.0.0-20191007182048-72f939374954/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
24
- golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
25
- golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
26
- golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
27
- golang.org/x/sys v0.0.0-20191008105621-543471e840be h1:QAcqgptGM8IQBC9K/RC4o+O9YmqEm0diQn9QmZw/0mU=
28
- golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
29
- golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
30
- golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
31
- golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
32
- golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
33
- golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7 h1:9zdDQZ7Thm29KFXgAX/+yaf3eVbP7djjWp/dXAppNCc=
34
- golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
35
- gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
36
- gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
37
- gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
38
- gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
39
- gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
40
- gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
41
- gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
42
- gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
43
- gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
1
+ github.com/bsm/ginkgo v1.16.1 h1:jp1v1dbmbGZDWmnGXDTN+XK3U1fTTNja9xYa7VBI0l0=
2
+ github.com/bsm/ginkgo v1.16.1/go.mod h1:RabIZLzOCPghgHJKUqHZpqrQETA5AnF4aCSIYy5C1bk=
3
+ github.com/bsm/gomega v1.11.0 h1:wg9DVGPETNZLIbMsseneMV1a7uo/x+wsCyNXdEcifDI=
4
+ github.com/bsm/gomega v1.11.0/go.mod h1:JifAceMQ4crZIWYUKrlGcmbN3bqHogVTADMD2ATsbwk=
5
+ github.com/golang-jwt/jwt v3.2.1+incompatible h1:73Z+4BJcrTC+KczS6WvTPvRGOp1WmfEP4Q1lOd9Z/+c=
6
+ github.com/golang-jwt/jwt v3.2.1+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
data/lib/firejwt.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  module FireJWT
2
- autoload :KeySet, 'firejwt/key_set'
2
+ autoload :Certificates, 'firejwt/certificates'
3
3
  autoload :Validator, 'firejwt/validator'
4
4
 
5
5
  class Token < Hash
@@ -4,7 +4,7 @@ require 'uri'
4
4
  require 'openssl'
5
5
 
6
6
  module FireJWT
7
- class KeySet < Hash
7
+ class Certificates
8
8
  URL = 'https://www.googleapis.com/robot/v1/metadata/x509/securetoken@system.gserviceaccount.com'.freeze
9
9
 
10
10
  attr_reader :expires_at
@@ -12,14 +12,17 @@ module FireJWT
12
12
  def initialize(url: URL)
13
13
  super()
14
14
 
15
- @url = URI(url)
15
+ @url = URI(url)
16
+ @keys = {}
17
+
16
18
  expire!
17
19
  refresh!
18
20
  end
19
21
 
20
- def get(key)
22
+ def get(kid)
21
23
  refresh! if expired?
22
- self[key]
24
+
25
+ @keys[kid]
23
26
  end
24
27
 
25
28
  def refresh!(limit = 5)
@@ -33,8 +36,11 @@ module FireJWT
33
36
  raise ArgumentError, 'Expires header not included in the response' unless resp['expires']
34
37
 
35
38
  @expires_at = Time.httpdate(resp['expires'])
36
- JSON.parse(resp.body).each do |kid, cert|
37
- store kid, OpenSSL::X509::Certificate.new(cert).public_key
39
+ @keys.clear
40
+
41
+ JSON.parse(resp.body).each do |kid, pem|
42
+ cert = OpenSSL::X509::Certificate.new(pem)
43
+ @keys.store kid, cert.public_key
38
44
  end
39
45
  end
40
46
 
@@ -3,46 +3,48 @@ require 'jwt'
3
3
  require 'net/http'
4
4
 
5
5
  module FireJWT
6
+ class InvalidAuthTimeError < JWT::DecodeError; end
7
+
8
+ # Validator validates tokens applying guidelines outlined in
9
+ # https://firebase.google.com/docs/auth/admin/verify-id-tokens#verify_id_tokens_using_a_third-party_jwt_library.
6
10
  class Validator
7
- # @param [Hash] opts
8
- # @option opts [String] :algorithm the expected algorithm. Default: RS256.
9
- # @option opts [String] :aud verify the audience claim against the given value. Default: nil (= do not validate).
10
- # @option opts [String] :iss verify the issuer claim against the given value. Default: nil (= do not verify).
11
- # @option opts [String] :sub verify the subject claim against the given value. Default: nil (= do not verify).
12
- # @option opts [Boolean] :verify_iat verify the issued at claim. Default: false.
13
- # @option opts [Integer] :exp_leeway expiration leeway in seconds. Default: none.
14
- def initialize(**opts)
15
- @defaults = opts.dup
16
- @keys = KeySet.new
11
+ # @param [String] project_id the unique identifier for your Firebase project, which can be found in the URL of that project's console.
12
+ def initialize(project_id)
13
+ project_id = project_id.to_s
14
+
15
+ @certs = Certificates.new
16
+ @opts = {
17
+ algorithms: %w[RS256].freeze,
18
+
19
+ # exp must be in the future, iat must be in the past
20
+ verify_expiration: true,
21
+ verify_iat: true,
22
+
23
+ # aud must be your Firebase project ID
24
+ verify_aud: true, aud: project_id,
25
+
26
+ # iss must be "https://securetoken.google.com/<projectId>"
27
+ verify_iss: true, iss: "https://securetoken.google.com/#{project_id}",
28
+ }
17
29
  end
18
30
 
19
31
  # @param [String] token the token string
20
- # @param [Hash] opts options
21
- # @option opts [Boolean] :allow_expired allow expired tokens. Default: false.
22
- # @option opts [String] :algorithm the expected algorithm. Default: RS256.
23
- # @option opts [String] :aud verify the audience claim against the given value. Default: nil (= do not validate).
24
- # @option opts [String] :iss verify the issuer claim against the given value. Default: nil (= do not verify).
25
- # @option opts [String] :sub verify the subject claim against the given value. Default: nil (= do not verify).
26
- # @option opts [Boolean] :verify_iat verify the issued at claim. Default: false.
27
- # @option opts [Integer] :exp_leeway expiration leeway in seconds. Default: none.
28
32
  # @return [FireJWT::Token] the token
29
33
  # @raises [JWT::DecodeError] validation errors
30
- def decode(token, allow_expired: false, **opts)
31
- opts = norm_opts(@defaults.merge(opts))
32
- payload, header = JWT.decode token, nil, !allow_expired, opts do |header|
33
- @keys.get(header['kid'])
34
+ def decode(token)
35
+ payload, header = JWT.decode token, nil, true, **@opts do |header|
36
+ @certs.get(header['kid'])
34
37
  end
35
- Token.new(payload, header)
36
- end
37
38
 
38
- private
39
+ # sub must be a non-empty string
40
+ sub = payload['sub']
41
+ raise(JWT::InvalidSubError, 'Invalid subject. Expected non-empty string') unless sub.is_a?(String) && !sub.empty?
39
42
 
40
- def norm_opts(opts)
41
- opts[:verify_aud] = opts.key?(:aud) unless opts.key?(:verify_aud)
42
- opts[:verify_iss] = opts.key?(:iss) unless opts.key?(:verify_iss)
43
- opts[:verify_sub] = opts.key?(:sub) unless opts.key?(:verify_sub)
44
- opts[:algorithm] ||= 'RS256'
45
- opts
43
+ # auth_time must be in the past
44
+ aut = payload['auth_time']
45
+ raise(InvalidAuthTimeError, 'Invalid auth_time') if !aut.is_a?(Numeric) || aut.to_f > Time.now.to_f
46
+
47
+ Token.new(payload, header)
46
48
  end
47
49
  end
48
50
  end
@@ -1,28 +1,28 @@
1
1
  require 'spec_helper'
2
2
 
3
- RSpec.describe FireJWT::KeySet do
4
- let! :keys_request do
3
+ RSpec.describe FireJWT::Certificates do
4
+ let(:cert) { MockCert.new }
5
+
6
+ let! :http_request do
5
7
  stub_request(:get, described_class::URL.to_s).to_return(
6
8
  status: 200,
7
9
  headers: { expires: (Time.now + 3600).httpdate },
8
- body: MOCK_RESPONSE.to_json,
10
+ body: cert.to_json,
9
11
  )
10
12
  end
11
13
 
12
- it 'should init' do
13
- expect(subject).to include(
14
- MOCK_KID => instance_of(OpenSSL::PKey::RSA),
15
- )
14
+ it 'inits' do
16
15
  expect(subject.expires_at).to be_within(10).of(Time.now + 3600)
17
16
  expect(subject).not_to be_expired
17
+ expect(http_request).to have_been_made
18
18
  end
19
19
 
20
- it 'should retrieve keys' do
20
+ it 'retrieves keys' do
21
21
  expect(subject.get('BAD')).to be_nil
22
- expect(subject.get(MOCK_KID)).to be_instance_of(OpenSSL::PKey::RSA)
22
+ expect(subject.get(cert.kid)).to be_instance_of(OpenSSL::PKey::RSA)
23
23
  end
24
24
 
25
- it 'should check/update expiration status' do
25
+ it 'check/updates expiration status' do
26
26
  expect(subject).not_to be_expired
27
27
  subject.expire!
28
28
  expect(subject).to be_expired
@@ -1,71 +1,86 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  RSpec.describe FireJWT::Validator do
4
- let! :keys_request do
5
- stub_request(:get, FireJWT::KeySet::URL.to_s).to_return(
4
+ subject { described_class.new(project_id) }
5
+
6
+ let! :http_request do
7
+ stub_request(:get, FireJWT::Certificates::URL.to_s).to_return(
6
8
  status: 200,
7
9
  headers: { expires: (Time.now + 3600).httpdate },
8
- body: MOCK_RESPONSE.to_json,
10
+ body: cert.to_json,
9
11
  )
10
12
  end
11
13
 
12
- let :exp_time do
13
- Time.now.to_i + 3600
14
- end
15
-
16
- let :token do
17
- payload = {
18
- sub: 'me@example.com',
19
- aud: 'you',
20
- iss: 'me',
21
- exp: exp_time,
14
+ let :payload do
15
+ now = Time.now.to_i
16
+ {
17
+ 'name' => 'Me',
18
+ 'picture' => 'https://test.host/me.jpg',
19
+ 'sub' => 'MDYwNDQwNjUtYWQ0ZC00ZDkwLThl',
20
+ 'user_id' => 'MDYwNDQwNjUtYWQ0ZC00ZDkwLThl',
21
+ 'aud' => project_id,
22
+ 'iss' => 'https://securetoken.google.com/' << project_id,
23
+ 'iat' => now - 1800,
24
+ 'exp' => now + 3600,
25
+ 'auth_time' => now,
26
+ 'email' => 'me@example.com',
27
+ 'email_verified' => true,
28
+ 'firebase' => {
29
+ 'sign_in_provider' => 'google.com',
30
+ 'identities' => {
31
+ 'google.com' => ['123123123123123123123'],
32
+ 'email' => ['me@example.com'],
33
+ },
34
+ },
22
35
  }
23
- JWT.encode payload, MOCK_RSA, 'RS256', kid: MOCK_KID
24
36
  end
25
37
 
26
- it 'should decode' do
38
+ let(:cert) { MockCert.new }
39
+ let(:project_id) { 'mock-project' }
40
+ let(:token) { JWT.encode payload, cert.pkey, 'RS256', kid: cert.kid }
41
+
42
+ it 'decodes' do
27
43
  decoded = subject.decode(token)
28
44
  expect(decoded).to be_instance_of(FireJWT::Token)
29
- expect(decoded).to eq(
30
- 'sub' => 'me@example.com',
31
- 'aud' => 'you',
32
- 'iss' => 'me',
33
- 'exp' => exp_time,
34
- )
45
+ expect(decoded).to eq(payload)
35
46
  expect(decoded.header).to eq(
36
47
  'alg' => 'RS256',
37
- 'kid' => 'e5a91d9f39fa4de254a1e89df00f05b7e248b985',
48
+ 'kid' => cert.kid,
38
49
  )
50
+ expect(http_request).to have_been_made
39
51
  end
40
52
 
41
- it 'should normalize options' do
42
- expect(JWT).to receive(:decode).with(
43
- instance_of(String),
44
- nil,
45
- true,
46
- algorithm: 'RS256',
47
- verify_aud: false,
48
- verify_iss: false,
49
- verify_sub: false,
50
- ).and_return([{}, {}])
51
- subject.decode(token)
52
- end
53
- it 'should reject bad tokens' do
53
+ it 'rejects bad tokens' do
54
54
  expect { subject.decode('BAD') }.to raise_error(JWT::DecodeError)
55
55
  end
56
56
 
57
- it 'should verify audiences' do
58
- expect(subject.decode(token, aud: 'you')).to be_instance_of(FireJWT::Token)
59
- expect { subject.decode(token, aud: 'other') }.to raise_error(JWT::InvalidAudError)
57
+ it 'verifies exp' do
58
+ payload['exp'] = Time.now.to_i - 1
59
+ expect { subject.decode(token) }.to raise_error(JWT::ExpiredSignature)
60
+ end
61
+
62
+ it 'verifies iat' do
63
+ payload['iat'] = Time.now.to_i + 10
64
+ expect { subject.decode(token) }.to raise_error(JWT::InvalidIatError)
65
+ end
66
+
67
+ it 'verifies aud' do
68
+ payload['aud'] = 'other'
69
+ expect { subject.decode(token) }.to raise_error(JWT::InvalidAudError)
70
+ end
71
+
72
+ it 'verifies iss' do
73
+ payload['iss'] = 'other'
74
+ expect { subject.decode(token) }.to raise_error(JWT::InvalidIssuerError)
60
75
  end
61
76
 
62
- it 'should verify issuers' do
63
- expect(subject.decode(token, iss: 'me')).to be_instance_of(FireJWT::Token)
64
- expect { subject.decode(token, iss: 'other') }.to raise_error(JWT::InvalidIssuerError)
77
+ it 'verifies sub' do
78
+ payload['sub'] = ''
79
+ expect { subject.decode(token) }.to raise_error(JWT::InvalidSubError)
65
80
  end
66
81
 
67
- it 'should verify subjects' do
68
- expect(subject.decode(token, sub: 'me@example.com')).to be_instance_of(FireJWT::Token)
69
- expect { subject.decode(token, sub: 'other') }.to raise_error(JWT::InvalidSubError)
82
+ it 'verifies auth_time' do
83
+ payload['auth_time'] = Time.now.to_i + 10
84
+ expect { subject.decode(token) }.to raise_error(FireJWT::InvalidAuthTimeError)
70
85
  end
71
86
  end
data/spec/spec_helper.rb CHANGED
@@ -4,8 +4,34 @@ require 'webmock/rspec'
4
4
 
5
5
  WebMock.disable_net_connect!
6
6
 
7
- MOCK_KID = 'e5a91d9f39fa4de254a1e89df00f05b7e248b985'.freeze
8
- MOCK_RSA = OpenSSL::PKey::RSA.new File.read(File.expand_path('../testdata/priv.pem', __dir__))
9
- MOCK_RESPONSE = {
10
- MOCK_KID => File.read(File.expand_path('../testdata/cert.pem', __dir__)),
11
- }.freeze
7
+ class MockCert
8
+ attr_reader :cert, :pkey
9
+
10
+ def initialize
11
+ @pkey = OpenSSL::PKey::RSA.new 2048
12
+ @cert = OpenSSL::X509::Certificate.new
13
+ @cert.version = 2
14
+ @cert.serial = 2605014480174073526
15
+ @cert.subject = OpenSSL::X509::Name.parse('/CN=securetoken.system.gserviceaccount.com')
16
+ @cert.issuer = @cert.subject
17
+ @cert.public_key = @pkey.public_key
18
+ @cert.not_before = Time.now
19
+ @cert.not_after = @cert.not_before + 3600
20
+
21
+ exts = OpenSSL::X509::ExtensionFactory.new
22
+ exts.subject_certificate = cert
23
+ exts.issuer_certificate = cert
24
+ @cert.add_extension(exts.create_extension('basicConstraints', 'CA:FALSE', true))
25
+ @cert.add_extension(exts.create_extension('keyUsage', 'Digital Signature', true))
26
+ @cert.add_extension(exts.create_extension('extendedKeyUsage', 'TLS Web Client Authentication', true))
27
+ @cert.sign(@pkey, OpenSSL::Digest.new('SHA256'))
28
+ end
29
+
30
+ def kid
31
+ @kid ||= Digest::SHA1.hexdigest(@cert.to_der)
32
+ end
33
+
34
+ def to_json(*)
35
+ { kid => @cert }.to_json
36
+ end
37
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: firejwt
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.3.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Black Square Media Ltd
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-06-11 00:00:00.000000000 Z
11
+ date: 2021-07-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: jwt
@@ -53,7 +53,7 @@ dependencies:
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
- name: rubocop
56
+ name: rubocop-bsm
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - ">="
@@ -87,29 +87,28 @@ executables: []
87
87
  extensions: []
88
88
  extra_rdoc_files: []
89
89
  files:
90
+ - ".github/workflows/lint.yml"
91
+ - ".github/workflows/test.yml"
90
92
  - ".gitignore"
91
93
  - ".rubocop.yml"
92
- - ".travis.yml"
93
94
  - Gemfile
94
95
  - Gemfile.lock
95
96
  - LICENSE
96
97
  - Makefile
97
98
  - README.md
98
99
  - Rakefile
100
+ - ext_test.go
99
101
  - firejwt.gemspec
100
102
  - firejwt.go
101
103
  - firejwt_test.go
102
104
  - go.mod
103
105
  - go.sum
104
106
  - lib/firejwt.rb
105
- - lib/firejwt/key_set.rb
107
+ - lib/firejwt/certificates.rb
106
108
  - lib/firejwt/validator.rb
107
- - opt.go
108
- - spec/firejwt/key_set_spec.rb
109
+ - spec/firejwt/certificates_spec.rb
109
110
  - spec/firejwt/validator_spec.rb
110
111
  - spec/spec_helper.rb
111
- - testdata/cert.pem
112
- - testdata/priv.pem
113
112
  homepage: https://github.com/bsm/firejwt
114
113
  licenses:
115
114
  - Apache-2.0
@@ -129,11 +128,11 @@ required_rubygems_version: !ruby/object:Gem::Requirement
129
128
  - !ruby/object:Gem::Version
130
129
  version: '0'
131
130
  requirements: []
132
- rubygems_version: 3.1.4
131
+ rubygems_version: 3.2.15
133
132
  signing_key:
134
133
  specification_version: 4
135
134
  summary: Firebase JWT validation
136
135
  test_files:
137
- - spec/firejwt/key_set_spec.rb
136
+ - spec/firejwt/certificates_spec.rb
138
137
  - spec/firejwt/validator_spec.rb
139
138
  - spec/spec_helper.rb