otp-jwt 0.1.0 → 0.2.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
  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: