Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,19 @@ Gemspec/DevelopmentDependencies:

Naming/PredicateMethod:
Enabled: false

Style/MethodCallWithArgsParentheses:
Enabled: true
Exclude:
- "*.gemspec"
AllowedMethods:
- raise
- fail
- yield
- to
- not_to
- to_not
- describe
- context
- it
- specify
2 changes: 1 addition & 1 deletion lib/jwt/jwa/hmac.rb
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ def fixed_length_secure_compare(a, b)
def fixed_length_secure_compare(a, b)
raise ArgumentError, "string length mismatch." unless a.bytesize == b.bytesize

l = a.unpack "C#{a.bytesize}"
l = a.unpack("C#{a.bytesize}")

res = 0
b.each_byte { |byte| res |= byte ^ l.shift }
Expand Down
2 changes: 1 addition & 1 deletion lib/jwt/jwk/ec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ def members

def export(options = {})
exported = parameters.clone
exported.reject! { |k, _| EC_PRIVATE_KEY_ELEMENTS.include? k } unless private? && options[:include_private] == true
exported.reject! { |k, _| EC_PRIVATE_KEY_ELEMENTS.include?(k) } unless private? && options[:include_private] == true
exported
end

Expand Down
2 changes: 1 addition & 1 deletion lib/jwt/jwk/hmac.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ def signing_key
# See https://tools.ietf.org/html/rfc7517#appendix-A.3
def export(options = {})
exported = parameters.clone
exported.reject! { |k, _| HMAC_PRIVATE_KEY_ELEMENTS.include? k } unless private? && options[:include_private] == true
exported.reject! { |k, _| HMAC_PRIVATE_KEY_ELEMENTS.include?(k) } unless private? && options[:include_private] == true
exported
end

Expand Down
2 changes: 1 addition & 1 deletion lib/jwt/jwk/rsa.rb
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ def verify_key

def export(options = {})
exported = parameters.clone
exported.reject! { |k, _| RSA_PRIVATE_KEY_ELEMENTS.include? k } unless private? && options[:include_private] == true
exported.reject! { |k, _| RSA_PRIVATE_KEY_ELEMENTS.include?(k) } unless private? && options[:include_private] == true

exported
end
Expand Down
119 changes: 52 additions & 67 deletions spec/integration/readme_examples_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,64 +7,49 @@
let(:payload) { { data: 'test' } }

it 'NONE' do
token = JWT.encode payload, nil, 'none'
decoded_token = JWT.decode token, nil, false

expect(token).to eq 'eyJhbGciOiJub25lIn0.eyJkYXRhIjoidGVzdCJ9.'
expect(decoded_token).to eq [
{ 'data' => 'test' },
{ 'alg' => 'none' }
]
token = JWT.encode(payload, nil, 'none')
decoded_token = JWT.decode(token, nil, false)

expect(token).to eq('eyJhbGciOiJub25lIn0.eyJkYXRhIjoidGVzdCJ9.')
expect(decoded_token).to eq([{ 'data' => 'test' }, { 'alg' => 'none' }])
end

it 'decodes with HMAC algorithm with secret key' do
token = JWT.encode payload, 'my$ecretK3y', 'HS256'
decoded_token = JWT.decode token, 'my$ecretK3y', false

expect(token).to eq 'eyJhbGciOiJIUzI1NiJ9.eyJkYXRhIjoidGVzdCJ9.pNIWIL34Jo13LViZAJACzK6Yf0qnvT_BuwOxiMCPE-Y'
expect(decoded_token).to eq [
{ 'data' => 'test' },
{ 'alg' => 'HS256' }
]
token = JWT.encode(payload, 'my$ecretK3y', 'HS256')
decoded_token = JWT.decode(token, 'my$ecretK3y', false)

expect(token).to eq('eyJhbGciOiJIUzI1NiJ9.eyJkYXRhIjoidGVzdCJ9.pNIWIL34Jo13LViZAJACzK6Yf0qnvT_BuwOxiMCPE-Y')
expect(decoded_token).to eq([{ 'data' => 'test' }, { 'alg' => 'HS256' }])
end

it 'RSA' do
rsa_private = OpenSSL::PKey::RSA.generate 2048
rsa_private = OpenSSL::PKey::RSA.generate(2048)
rsa_public = rsa_private.public_key

token = JWT.encode payload, rsa_private, 'RS256'
decoded_token = JWT.decode token, rsa_public, true, algorithm: 'RS256'
token = JWT.encode(payload, rsa_private, 'RS256')
decoded_token = JWT.decode(token, rsa_public, true, algorithm: 'RS256')

expect(decoded_token).to eq [
{ 'data' => 'test' },
{ 'alg' => 'RS256' }
]
expect(decoded_token).to eq([{ 'data' => 'test' }, { 'alg' => 'RS256' }])
end

it 'ECDSA' do
ecdsa_key = OpenSSL::PKey::EC.generate('prime256v1')

token = JWT.encode payload, ecdsa_key, 'ES256'
decoded_token = JWT.decode token, ecdsa_key, true, algorithm: 'ES256'
token = JWT.encode(payload, ecdsa_key, 'ES256')
decoded_token = JWT.decode(token, ecdsa_key, true, algorithm: 'ES256')

expect(decoded_token).to eq [
{ 'data' => 'test' },
{ 'alg' => 'ES256' }
]
expect(decoded_token).to eq([{ 'data' => 'test' }, { 'alg' => 'ES256' }])
end

if Gem::Version.new(OpenSSL::VERSION) >= Gem::Version.new('2.1')
it 'RSASSA-PSS' do
rsa_private = OpenSSL::PKey::RSA.generate 2048
rsa_private = OpenSSL::PKey::RSA.generate(2048)
rsa_public = rsa_private.public_key

token = JWT.encode payload, rsa_private, 'PS256'
decoded_token = JWT.decode token, rsa_public, true, algorithm: 'PS256'
token = JWT.encode(payload, rsa_private, 'PS256')
decoded_token = JWT.decode(token, rsa_public, true, algorithm: 'PS256')

expect(decoded_token).to eq [
{ 'data' => 'test' },
{ 'alg' => 'PS256' }
]
expect(decoded_token).to eq([{ 'data' => 'test' }, { 'alg' => 'PS256' }])
end
end
end
Expand All @@ -77,10 +62,10 @@
exp = Time.now.to_i + (4 * 3600)
exp_payload = { data: 'data', exp: exp }

token = JWT.encode exp_payload, hmac_secret, 'HS256'
token = JWT.encode(exp_payload, hmac_secret, 'HS256')

expect do
JWT.decode token, hmac_secret, true, algorithm: 'HS256'
JWT.decode(token, hmac_secret, true, algorithm: 'HS256')
end.not_to raise_error
end

Expand All @@ -90,10 +75,10 @@

exp_payload = { data: 'data', exp: exp }

token = JWT.encode exp_payload, hmac_secret, 'HS256'
token = JWT.encode(exp_payload, hmac_secret, 'HS256')

expect do
JWT.decode token, hmac_secret, true, leeway: leeway, algorithm: 'HS256'
JWT.decode(token, hmac_secret, true, leeway: leeway, algorithm: 'HS256')
end.not_to raise_error
end
end
Expand All @@ -102,21 +87,21 @@
it 'without leeway' do
nbf = Time.now.to_i - 3600
nbf_payload = { data: 'data', nbf: nbf }
token = JWT.encode nbf_payload, hmac_secret, 'HS256'
token = JWT.encode(nbf_payload, hmac_secret, 'HS256')

expect do
JWT.decode token, hmac_secret, true, algorithm: 'HS256'
JWT.decode(token, hmac_secret, true, algorithm: 'HS256')
end.not_to raise_error
end

it 'with leeway' do
nbf = Time.now.to_i + 10
leeway = 30
nbf_payload = { data: 'data', nbf: nbf }
token = JWT.encode nbf_payload, hmac_secret, 'HS256'
token = JWT.encode(nbf_payload, hmac_secret, 'HS256')

expect do
JWT.decode token, hmac_secret, true, leeway: leeway, algorithm: 'HS256'
JWT.decode(token, hmac_secret, true, leeway: leeway, algorithm: 'HS256')
end.not_to raise_error
end
end
Expand All @@ -125,10 +110,10 @@
iss = 'My Awesome Company Inc. or https://my.awesome.website/'
iss_payload = { data: 'data', iss: iss }

token = JWT.encode iss_payload, hmac_secret, 'HS256'
token = JWT.encode(iss_payload, hmac_secret, 'HS256')

expect do
JWT.decode token, hmac_secret, true, iss: iss, algorithm: 'HS256'
JWT.decode(token, hmac_secret, true, iss: iss, algorithm: 'HS256')
end.not_to raise_error
end

Expand All @@ -137,21 +122,21 @@
aud = %w[Young Old]
aud_payload = { data: 'data', aud: aud }

token = JWT.encode aud_payload, hmac_secret, 'HS256'
token = JWT.encode(aud_payload, hmac_secret, 'HS256')

expect do
JWT.decode token, hmac_secret, true, aud: %w[Old Young], verify_aud: true, algorithm: 'HS256'
JWT.decode(token, hmac_secret, true, aud: %w[Old Young], verify_aud: true, algorithm: 'HS256')
end.not_to raise_error
end

it 'string' do
aud = 'Kids'
aud_payload = { data: 'data', aud: aud }

token = JWT.encode aud_payload, hmac_secret, 'HS256'
token = JWT.encode(aud_payload, hmac_secret, 'HS256')

expect do
JWT.decode token, hmac_secret, true, aud: 'Kids', verify_aud: true, algorithm: 'HS256'
JWT.decode(token, hmac_secret, true, aud: 'Kids', verify_aud: true, algorithm: 'HS256')
end.not_to raise_error
end
end
Expand All @@ -163,10 +148,10 @@
jti = Digest::MD5.hexdigest(jti_raw)
jti_payload = { data: 'data', iat: iat, jti: jti }

token = JWT.encode jti_payload, hmac_secret, 'HS256'
token = JWT.encode(jti_payload, hmac_secret, 'HS256')

expect do
JWT.decode token, hmac_secret, true, verify_jti: true, algorithm: 'HS256'
JWT.decode(token, hmac_secret, true, verify_jti: true, algorithm: 'HS256')
end.not_to raise_error
end

Expand All @@ -175,21 +160,21 @@
iat = Time.now.to_i
iat_payload = { data: 'data', iat: iat }

token = JWT.encode iat_payload, hmac_secret, 'HS256'
token = JWT.encode(iat_payload, hmac_secret, 'HS256')

expect do
JWT.decode token, hmac_secret, true, verify_iat: true, algorithm: 'HS256'
JWT.decode(token, hmac_secret, true, verify_iat: true, algorithm: 'HS256')
end.not_to raise_error
end

it 'with leeway' do
iat = Time.now.to_i - 7
iat_payload = { data: 'data', iat: iat, leeway: 10 }

token = JWT.encode iat_payload, hmac_secret, 'HS256'
token = JWT.encode(iat_payload, hmac_secret, 'HS256')

expect do
JWT.decode token, hmac_secret, true, verify_iat: true, algorithm: 'HS256'
JWT.decode(token, hmac_secret, true, verify_iat: true, algorithm: 'HS256')
end.not_to raise_error
end
end
Expand All @@ -198,43 +183,43 @@
it 'with custom field' do
payload = { data: 'test' }

token = JWT.encode payload, nil, 'none', typ: 'JWT'
_, header = JWT.decode token, nil, false
token = JWT.encode(payload, nil, 'none', typ: 'JWT')
_, header = JWT.decode(token, nil, false)

expect(header['typ']).to eq 'JWT'
expect(header['typ']).to eq('JWT')
end
end

it 'sub' do
sub = 'Subject'
sub_payload = { data: 'data', sub: sub }

token = JWT.encode sub_payload, hmac_secret, 'HS256'
token = JWT.encode(sub_payload, hmac_secret, 'HS256')

expect do
JWT.decode token, hmac_secret, true, { sub: sub, verify_sub: true, algorithm: 'HS256' }
JWT.decode(token, hmac_secret, true, { sub: sub, verify_sub: true, algorithm: 'HS256' })
end.not_to raise_error

expect do
JWT.decode token, hmac_secret, true, { sub: 'sub', verify_sub: true, algorithm: 'HS256' }
JWT.decode(token, hmac_secret, true, { sub: 'sub', verify_sub: true, algorithm: 'HS256' })
end.to raise_error(JWT::InvalidSubError)

expect do
JWT.decode token, hmac_secret, true, { 'sub' => 'sub', verify_sub: true, algorithm: 'HS256' }
JWT.decode(token, hmac_secret, true, { 'sub' => 'sub', verify_sub: true, algorithm: 'HS256' })
end.not_to raise_error
end

it 'required_claims' do
payload = { data: 'test' }

token = JWT.encode payload, hmac_secret, 'HS256'
token = JWT.encode(payload, hmac_secret, 'HS256')

expect do
JWT.decode token, hmac_secret, true, required_claims: ['exp'], algorithm: 'HS256'
JWT.decode(token, hmac_secret, true, required_claims: ['exp'], algorithm: 'HS256')
end.to raise_error(JWT::MissingRequiredClaim)

expect do
JWT.decode token, hmac_secret, true, required_claims: ['data'], algorithm: 'HS256'
JWT.decode(token, hmac_secret, true, required_claims: ['data'], algorithm: 'HS256')
end.not_to raise_error
end

Expand All @@ -244,7 +229,7 @@

secrets = { issuers.first => hmac_secret, issuers.last => 'hmac_secret2' }

token = JWT.encode iss_payload, hmac_secret, 'HS256'
token = JWT.encode(iss_payload, hmac_secret, 'HS256')

expect do
# Add iss to the validation to check if the token has been manipulated
Expand Down
4 changes: 2 additions & 2 deletions spec/jwt/claims/audience_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
it 'raises JWT::InvalidAudError' do
expect do
subject
end.to raise_error JWT::InvalidAudError
end.to raise_error(JWT::InvalidAudError)
end
end

Expand All @@ -27,7 +27,7 @@
it 'raises JWT::InvalidAudError' do
expect do
subject
end.to raise_error JWT::InvalidAudError
end.to raise_error(JWT::InvalidAudError)
end
end

Expand Down
2 changes: 1 addition & 1 deletion spec/jwt/claims/not_before_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
describe '#verify!' do
context 'when nbf is in the future' do
it 'raises JWT::ImmatureSignature' do
expect { described_class.new(leeway: 0).verify!(context: SpecSupport::Token.new(payload: payload)) }.to raise_error JWT::ImmatureSignature
expect { described_class.new(leeway: 0).verify!(context: SpecSupport::Token.new(payload: payload)) }.to raise_error(JWT::ImmatureSignature)
end
end

Expand Down
8 changes: 4 additions & 4 deletions spec/jwt/claims/numeric_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,14 @@
let(:claims) { { claim => '1' } }

it 'raises error' do
expect { subject }.to raise_error JWT::InvalidPayload
expect { subject }.to raise_error(JWT::InvalidPayload)
end

context 'and key is a string' do
let(:claims) { { claim.to_s => '1' } }

it 'raises error' do
expect { subject }.to raise_error JWT::InvalidPayload
expect { subject }.to raise_error(JWT::InvalidPayload)
end
end
end
Expand All @@ -46,15 +46,15 @@
let(:claims) { { claim => Time.now } }

it 'raises error' do
expect { subject }.to raise_error JWT::InvalidPayload
expect { subject }.to raise_error(JWT::InvalidPayload)
end
end

context "when #{claim} payload is a string" do
let(:claims) { { claim => '1' } }

it 'raises error' do
expect { subject }.to raise_error JWT::InvalidPayload
expect { subject }.to raise_error(JWT::InvalidPayload)
end
end
end
Expand Down
Loading
Loading