diff --git a/README.md b/README.md index f01c4b7f..6a8edb24 100644 --- a/README.md +++ b/README.md @@ -112,18 +112,19 @@ the token option. For example: ```ruby claims = { application_id: application_id, + private_key: 'path/to/private.key', nbf: 1483315200, - exp: 1514764800, - iat: 1483228800 + ttl: 800 } -private_key = File.read('path/to/private.key') - -token = Nexmo::JWT.generate(claims, private_key) +token = Nexmo::JWT.generate(claims) client = Nexmo::Client.new(token: token) ```` +Documentation for the Nexmo Ruby JWT generator gem can be found at +[https://www.rubydoc.info/github/nexmo/nexmo-jwt-ruby](https://www.rubydoc.info/github/nexmo/nexmo-jwt-ruby). +The documentation outlines all the possible parameters you can use to customize and build a token with. ## Webhook signatures diff --git a/lib/nexmo/jwt.rb b/lib/nexmo/jwt.rb index 69379f82..296ab000 100644 --- a/lib/nexmo/jwt.rb +++ b/lib/nexmo/jwt.rb @@ -1,13 +1,11 @@ -# typed: strict +# typed: false # frozen_string_literal: true require 'securerandom' require 'openssl' -require 'jwt' +require 'nexmo-jwt' module Nexmo - module JWT - extend T::Sig - + class JWT # Generate an encoded JSON Web Token. # # By default the Nexmo Ruby SDK generates a short lived JWT per request. @@ -16,12 +14,14 @@ module JWT # directly call {Nexmo::JWT.generate} to generate a token, and set the token # attribute on the client object. # + # Documentation for the Nexmo Ruby JWT generator gem can be found at + # https://www.rubydoc.info/github/nexmo/nexmo-jwt-ruby + # # @example # claims = { # application_id: application_id, - # nbf: 1483315200, - # exp: 1514764800, - # iat: 1483228800 + # ttl: 800, + # subject: 'My_Subject' # } # # private_key = File.read('path/to/private.key') @@ -33,15 +33,9 @@ module JWT # # @return [String] # - sig { params(payload: T::Hash[T.any(Symbol, String), T.any(String, Integer)], private_key: T.any(OpenSSL::PKey::RSA, String)).returns(String) } - def self.generate(payload, private_key) - payload[:iat] = iat = Time.now.to_i unless payload.key?(:iat) || payload.key?('iat') - payload[:exp] = T.must(iat) + 60 unless payload.key?(:exp) || payload.key?('exp') - payload[:jti] = SecureRandom.uuid unless payload.key?(:jti) || payload.key?('jti') - - private_key = OpenSSL::PKey::RSA.new(private_key) unless private_key.respond_to?(:sign) - - ::JWT.encode(payload, private_key, 'RS256') + def self.generate(payload, private_key = nil) + payload[:private_key] = private_key unless payload[:private_key] + @token = Nexmo::JWTBuilder.new(payload).jwt.generate end end end diff --git a/nexmo.gemspec b/nexmo.gemspec index b341a3a8..6993c56d 100644 --- a/nexmo.gemspec +++ b/nexmo.gemspec @@ -12,7 +12,7 @@ Gem::Specification.new do |s| s.summary = 'This is the Ruby client library for Nexmo\'s API. To use it you\'ll need a Nexmo account. Sign up for free at https://www.nexmo.com' s.files = Dir.glob('lib/**/*.rb') + %w(LICENSE.txt README.md nexmo.gemspec) s.required_ruby_version = '>= 2.5.0' - s.add_dependency('jwt', '~> 2') + s.add_dependency('nexmo-jwt', '~> 0.1') s.add_dependency('zeitwerk', '~> 2', '>= 2.2') s.add_dependency('sorbet-runtime', '~> 0.5') s.require_path = 'lib' diff --git a/test/nexmo/jwt_test.rb b/test/nexmo/jwt_test.rb index f9a4962a..168fd580 100644 --- a/test/nexmo/jwt_test.rb +++ b/test/nexmo/jwt_test.rb @@ -3,7 +3,7 @@ class Nexmo::JWTTest < Minitest::Test def private_key - @private_key ||= OpenSSL::PKey::RSA.new(1024) + @private_key ||= File.read('test/private_key.txt') end def application_id @@ -15,38 +15,42 @@ def uuid_pattern end def decode(token) - JWT.decode(token, private_key, _verify=true, {algorithm: 'RS256'}).first + JWT.decode(token, private_key, false, {algorithm: 'RS256'}).first end def test_generate_method_returns_payload_encoded_with_private_key time = Time.now.to_i payload = { - 'application_id' => application_id, - 'iat' => time, - 'exp' => time + 3600, - 'jti' => 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' + :application_id => application_id, + :private_key => private_key, + :iat => time, + :exp => time + 3600, + :jti => 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' } - token = Nexmo::JWT.generate(payload, private_key) + token = Nexmo::JWT.generate(payload) + decoded = decode(token) - assert_equal decode(token), payload + assert_equal decoded.fetch('application_id'), payload.fetch(:application_id) + assert_equal decoded.fetch('iat'), payload.fetch(:iat) + assert_equal decoded.fetch('jti'), payload.fetch(:jti) end def test_generate_method_sets_default_value_for_iat_parameter - token = Nexmo::JWT.generate({}, private_key) + token = Nexmo::JWT.generate({ :application_id => application_id }, private_key) assert_kind_of Integer, decode(token).fetch('iat') end def test_generate_method_sets_default_value_for_exp_parameter - token = Nexmo::JWT.generate({}, private_key) + token = Nexmo::JWT.generate({ :application_id => application_id }, private_key) assert_kind_of Integer, decode(token).fetch('exp') end def test_generate_method_sets_default_value_for_jti_parameter - token = Nexmo::JWT.generate({}, private_key) + token = Nexmo::JWT.generate({ :application_id => application_id }, private_key) assert_match uuid_pattern, decode(token).fetch('jti') end