otp-jwt 0.1.0 → 0.2.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 21a9ead6fc616488ac4b250bddf20522ed33d38b
4
- data.tar.gz: d2f7ebaf6e27df53693ca7ce9cb733967ede96e7
3
+ metadata.gz: 60c24eb465beb6f3763ba51b96242e0018a6973b
4
+ data.tar.gz: a5f581873f0c75488517116de8af8082593f331e
5
5
  SHA512:
6
- metadata.gz: d6b0faa09edf95831f1874200b28e87bf7da8d156f6f7af28940f28afe5e04b1ecb869d78278d88de2b4a6ae62ffb37dab31cea7110ae42d86f0497155e6f98e
7
- data.tar.gz: 1983f079088fc8b7b3a222ec6df065483f84d3ca072f369284b643ee024271b20cc865f7aa39ddbf2d84eadb90cbc8120748b69e1624ac0c75556f04e8e4e64e
6
+ metadata.gz: f1d6aaee52a096a13c4b56e368ae46ec608bcb0af58c2bed476fe083877e332b9b4b0cf634d6c759618a8f8687a0fc86a1911053703076e961d8081fd9020843
7
+ data.tar.gz: 24e616a845a2a162498c2d1b58f147badebbc3e46006bc762fff7a58c56ce0ec23508aafa113442647644e47d9138210eb0bd4881d436e21754c75d311fac991
data/Gemfile.lock CHANGED
@@ -3,7 +3,7 @@ PATH
3
3
  specs:
4
4
  otp-jwt (0.1.0)
5
5
  activesupport
6
- jwt (~> 2.1)
6
+ jwt (~> 2.2.0.pre.beta.0)
7
7
  rotp (~> 4.1)
8
8
 
9
9
  GEM
@@ -67,7 +67,7 @@ GEM
67
67
  concurrent-ruby (~> 1.0)
68
68
  jaro_winkler (1.5.2)
69
69
  json (2.2.0)
70
- jwt (2.1.0)
70
+ jwt (2.2.0.pre.beta.0)
71
71
  loofah (2.2.3)
72
72
  crass (~> 1.0.2)
73
73
  nokogiri (>= 1.5.9)
@@ -184,7 +184,7 @@ DEPENDENCIES
184
184
  bundler
185
185
  ffaker
186
186
  otp-jwt!
187
- rails (~> 5)
187
+ rails
188
188
  rspec-rails
189
189
  rubocop-performance
190
190
  rubocop-rails_config
data/README.md CHANGED
@@ -27,7 +27,7 @@ The available features include:
27
27
  * Flexible models support for
28
28
  [counter based OTP](https://github.com/mdp/rotp#counter-based-otps)
29
29
  * Flexible JWT token generation helpers for models and arbitrary data
30
- * Pluggable authentication based on the OTP and JWT
30
+ * Pluggable authentication flow using the OTP and JWT
31
31
  * Pluggable OTP mailer
32
32
  * Pluggable OTP SMS background processing job
33
33
 
@@ -62,6 +62,7 @@ Or install it yourself as:
62
62
  * [JWT for Active Record models](#jwt-for-active-record-models)
63
63
  * [JWT authorization](#jwt-authorization)
64
64
  * [JWT authentication](#jwt-authentication)
65
+ * [JWT Tokens](#jwt-tokens)
65
66
 
66
67
  ---
67
68
 
@@ -119,6 +120,17 @@ class User < ActiveRecord::Base
119
120
  end
120
121
  ```
121
122
 
123
+ To customize the mailer subject, address and template, update the defaults:
124
+
125
+ ```ruby
126
+ require 'otp/mailer'
127
+
128
+ OTP::Mailer.default subject: 'Your App magic password 🗝️'
129
+ OTP::Mailer.default from: ENV['DEFAUL_MAILER_FROM']
130
+ # Tell mailer to use the template from app/views/otp/mailer/otp.html.erb
131
+ OTP::Mailer.prepend_view_path(Rails.root.join('app', 'views'))
132
+ ```
133
+
122
134
  #### SMS delivery support
123
135
 
124
136
  You can use the built-in job to deliver the OTP via SMS, just require it and
@@ -130,8 +142,14 @@ require 'otp/sms_otp_job'
130
142
  class User < ActiveRecord::Base
131
143
  include OTP::ActiveRecord
132
144
 
145
+ SMS_TEMPLATE = '%{otp} is your APP magic password 🗝️'
146
+
133
147
  def sms_otp
134
- OTP::SMSOTPJob.perform_later(phone_number, otp) if phone_number.present?
148
+ OTP::SMSOTPJob.perform_later(
149
+ phone_number,
150
+ otp,
151
+ SMS_TEMPLATE # <-- Optional text message template.
152
+ ) if phone_number.present?
135
153
  end
136
154
  end
137
155
  ```
@@ -238,6 +256,22 @@ The OTP delivery is handled by the `User#deliver_otp` method
238
256
  and can be customized. By default it will call the `sms_otp` method and
239
257
  if nothing is returned, it will proceed with the `email_otp` method.
240
258
 
259
+ ### JWT Tokens
260
+
261
+ To help sign any sort of data, a lightweight JWT Token wrapper is provided.
262
+
263
+ Signing a payload will follow the pre-defined settings like the lifetime and
264
+ the encryption key. Decoding a token will validate any claims as well. Finally
265
+ there's a safe wrapper to help you with the JWT specific exceptions handling.
266
+
267
+ ```ruby
268
+ require 'otp/jwt/token'
269
+
270
+ token = OTP::JWT::Token.sign(sub: 'my subject')
271
+ OTP::JWT::Token.decode(token) == {'sub' => 'my subject'}
272
+ OTP::JWT::Token.decode('bad token') == nil
273
+ ```
274
+
241
275
  ## Development
242
276
 
243
277
  After checking out the repo, run `bundle` to install dependencies.
data/lib/otp/jwt/token.rb CHANGED
@@ -7,15 +7,6 @@ module OTP
7
7
  module Token
8
8
  include ActiveSupport::Configurable
9
9
 
10
- # Resolves possible JWT exception classes
11
- #
12
- # Can be removed once #255 is merged.
13
- # See: https://github.com/jwt/ruby-jwt/pull/255
14
- JWT_EXCEPTIONS = ::JWT.constants.map do |cname|
15
- klass = ::JWT.const_get(cname)
16
- klass if klass.is_a?(Class) && klass <= StandardError
17
- end.compact
18
-
19
10
  # The signature key used to sign the tokens.
20
11
  config_accessor :jwt_signature_key, instance_accessor: false
21
12
  # The signature key algorithm, defaults to HS256.
@@ -29,9 +20,12 @@ module OTP
29
20
  # @param claims [Hash], extra claims to be encoded into the token.
30
21
  #
31
22
  # @return [String], a JWT token
32
- def self.sign(payload, claims = {})
33
- payload = payload.merge(claims)
34
- claims[:exp] ||= self.jwt_lifetime if self.jwt_lifetime.present?
23
+ def self.sign(payload)
24
+ payload = payload.dup.as_json
25
+
26
+ if payload['exp'].blank? && self.jwt_lifetime.to_i > 0
27
+ payload['exp'] = Time.now.to_i + self.jwt_lifetime
28
+ end
35
29
 
36
30
  ::JWT.encode(payload, self.jwt_signature_key, self.jwt_algorithm)
37
31
  end
@@ -39,15 +33,11 @@ module OTP
39
33
  # Verifies and returns decoded token data upon success
40
34
  #
41
35
  # @param token [String], token to be decoded.
42
- # @param options [Hash], extra options to be used during verification.
36
+ # @param opts [Hash], extra options to be used during verification.
43
37
  #
44
38
  # @return [Hash], JWT token payload
45
- def self.verify(token, options = {})
46
- lifetime = self.jwt_lifetime
47
- opts = {}.merge(options)
48
- opts[:verify_expiration] ||= lifetime if lifetime.present?
49
-
50
- ::JWT.decode(token.to_s, self.jwt_signature_key, true, opts)
39
+ def self.verify(token, opts = nil)
40
+ ::JWT.decode(token.to_s, self.jwt_signature_key, true, opts || {})
51
41
  end
52
42
 
53
43
  # Decodes a valid token into [Hash]
@@ -55,14 +45,17 @@ module OTP
55
45
  # Requires a block, yields JWT data. Will catch any JWT exception.
56
46
  #
57
47
  # @param token [String], token to be decoded.
58
- # @param options [Hash], extra options to be used during verification.
48
+ # @param opts [Hash], extra options to be used during verification.
59
49
  # @return [Hash] upon success
60
- def self.decode(token, options = nil)
61
- return unless block_given?
62
- verified, _ = self.verify(token, options || {})
63
-
64
- yield verified
65
- rescue *JWT_EXCEPTIONS
50
+ def self.decode(token, opts = nil)
51
+ verified, _ = self.verify(token, opts)
52
+
53
+ if block_given?
54
+ yield verified
55
+ else
56
+ verified
57
+ end
58
+ rescue ::JWT::EncodeError, ::JWT::DecodeError
66
59
  end
67
60
  end
68
61
  end
@@ -1,5 +1,5 @@
1
1
  module OTP
2
2
  module JWT
3
- VERSION = '0.1.0'
3
+ VERSION = '0.2.0'
4
4
  end
5
5
  end
@@ -7,7 +7,7 @@ end
7
7
 
8
8
  module OTP
9
9
  # Uses the AWS SNS API to send the OTP SMS message.
10
- class SMSOTPJob < ActiveJob::Base
10
+ class SMSJob < ActiveJob::Base
11
11
  # A generic template for the message body.
12
12
  TEMPLATE = '%{otp} is your magic password 🗝️'
13
13
  # Indicates if the messaging is disabled. Handy for testing purposes.
data/otp-jwt.gemspec CHANGED
@@ -20,7 +20,7 @@ Gem::Specification.new do |spec|
20
20
  spec.require_paths = ['lib']
21
21
 
22
22
  spec.add_dependency 'activesupport'
23
- spec.add_dependency 'jwt', '~> 2.1'
23
+ spec.add_dependency 'jwt', '~> 2.2.0.pre.beta.0'
24
24
  spec.add_dependency 'rotp', '~> 4.1'
25
25
 
26
26
  spec.add_development_dependency 'bundler'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: otp-jwt
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stas Suscov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-03-31 00:00:00.000000000 Z
11
+ date: 2019-04-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -30,14 +30,14 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '2.1'
33
+ version: 2.2.0.pre.beta.0
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '2.1'
40
+ version: 2.2.0.pre.beta.0
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rotp
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -218,7 +218,7 @@ files:
218
218
  - lib/otp/jwt/version.rb
219
219
  - lib/otp/mailer.rb
220
220
  - lib/otp/mailer/otp.text.erb
221
- - lib/otp/sms_otp_job.rb
221
+ - lib/otp/sms_job.rb
222
222
  - otp-jwt.gemspec
223
223
  homepage: https://github.com/stas/otp-jwt
224
224
  licenses: