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 +4 -4
- data/Gemfile.lock +3 -3
- data/README.md +36 -2
- data/lib/otp/jwt/token.rb +19 -26
- data/lib/otp/jwt/version.rb +1 -1
- data/lib/otp/{sms_otp_job.rb → sms_job.rb} +1 -1
- data/otp-jwt.gemspec +1 -1
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 60c24eb465beb6f3763ba51b96242e0018a6973b
|
4
|
+
data.tar.gz: a5f581873f0c75488517116de8af8082593f331e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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.
|
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.
|
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
|
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
|
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(
|
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
|
33
|
-
payload = payload.
|
34
|
-
|
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
|
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,
|
46
|
-
|
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
|
48
|
+
# @param opts [Hash], extra options to be used during verification.
|
59
49
|
# @return [Hash] upon success
|
60
|
-
def self.decode(token,
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
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
|
data/lib/otp/jwt/version.rb
CHANGED
@@ -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
|
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.
|
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.
|
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-
|
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:
|
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:
|
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/
|
221
|
+
- lib/otp/sms_job.rb
|
222
222
|
- otp-jwt.gemspec
|
223
223
|
homepage: https://github.com/stas/otp-jwt
|
224
224
|
licenses:
|