jwt_api 0.1.0 → 0.1.1

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
  SHA256:
3
- metadata.gz: 19e4d4dcf76be937121c8a2559e64417c07c1218b352492985120076db85d4bd
4
- data.tar.gz: ba9ac0f21978e74a0ada2837d6966b0d017b74043ab001948bb6c137184f9089
3
+ metadata.gz: b98af57b80db1d208e37fea555f8840b0ef28d975b450e3d4913e5b43b90e49c
4
+ data.tar.gz: 37ab658dbc48fcaf0dc6fa332f64f85a5a16a654a1b603855df72d4d00d049f1
5
5
  SHA512:
6
- metadata.gz: ba08a36a4111d4ecb70466481fbc67f55b62a831f56c866ce10e754af84e9091c570e5ce594043da49b3ec13cf389332e78beafcc5c30de02d6558a90a75b0a5
7
- data.tar.gz: d57636254090a1e52d2e9e4408a1925fe7b4accb265b32b4a6933cbddd3439bb255ced6e6c84d35f3f99bac36ca26fa97c8c1a4117a00c9f6f516add5f38185d
6
+ metadata.gz: 325cb78e50548492bf4537a0b89b59e2c8bf9541481b9fc75dad97174251b0e2a7697ef5b8183dc67461375614a8fe22f576a8262df63db63116c0a65be04a54
7
+ data.tar.gz: 32143ac809d4b48c0b0afdd0274c04061f4fd0b094c8e35179d59515a0aecbfa5eabd0bb4a0fbf259f95d3e75387bb789741ffd8cd809de412ada9b8fa78db27
data/Gemfile CHANGED
@@ -7,4 +7,4 @@ gemspec
7
7
 
8
8
  gem 'jwt', '~> 2.2', '>= 2.2.3'
9
9
  gem 'rake', '~> 13.0'
10
- # gem 'rspec', '~> 3.0'
10
+ gem 'rspec'
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- jwt_api (0.1.0)
4
+ jwt_api (0.1.1)
5
5
  jwt (~> 2.2, >= 2.2.3)
6
6
 
7
7
  GEM
@@ -25,13 +25,14 @@ GEM
25
25
  rspec-support (3.10.2)
26
26
 
27
27
  PLATFORMS
28
+ arm64-darwin-21
28
29
  x86_64-darwin-20
29
30
 
30
31
  DEPENDENCIES
31
32
  jwt (~> 2.2, >= 2.2.3)
32
33
  jwt_api!
33
34
  rake (~> 13.0)
34
- rspec (~> 3.0)
35
+ rspec
35
36
 
36
37
  BUNDLED WITH
37
38
  2.2.25
data/README.md CHANGED
@@ -51,7 +51,7 @@ Running via Spring preloader in process 56250
51
51
  == 20210827123255 AddJtiToUsers: migrated (0.0259s) ===========================
52
52
  ```
53
53
 
54
- Feel free to remove the gem from your Gemfile, you now have everything you need in your application.
54
+
55
55
  ## Usage
56
56
 
57
57
  1. Make sure that each user that needs access to the API has a JTI generated.
data/jwt_api-0.1.0.gem ADDED
Binary file
@@ -8,11 +8,7 @@ class Api::BaseController < ApplicationController
8
8
  protected
9
9
 
10
10
  def authenticate_request!
11
- unless user_id_in_token?
12
- render json: { errors: ['Unauthorized'] }, status: :unauthorized
13
- return
14
- end
15
- @current_user = User.find(auth_token[:user_id])
11
+ user_id_in_token?
16
12
  rescue JWT::VerificationError, JWT::DecodeError
17
13
  render json: { errors: ['Unauthorized'] }, status: :unauthorized
18
14
  end
@@ -20,27 +16,33 @@ class Api::BaseController < ApplicationController
20
16
  private
21
17
 
22
18
  def http_token
23
- @http_token ||= if request.headers['Authorization'].present?
24
- request.headers['Authorization'].split.last
25
- end
19
+ @http_token ||= (request.headers['Authorization'].split.last if request.headers['Authorization'].present?)
26
20
  end
27
21
 
28
22
  def auth_token
29
- @auth_token ||= JsonWebToken.decode(http_token)
30
- rescue JWT::ExpiredSignature
31
- render json: { error: 'token expired' }
23
+ @auth_token ||= jwt.decode(http_token)[0].to_h.symbolize_keys!
24
+ return nil if token_expired?
25
+ return @auth_token if @auth_token.present? && @auth_token[:user_id].present? && jti_matches?
26
+ end
27
+
28
+ def token_expired?
29
+ @auth_token[:exp] < Time.now.to_i
32
30
  end
33
31
 
34
32
  def jti_matches?
35
- @current_user = User.find(auth_token[:user_id])
36
- !@current_user.jti.nil? && @current_user.jti == auth_token[:jti]
33
+ @current_user = User.find(@auth_token[:user_id])
34
+ @current_user&.jti == @auth_token[:jti]
37
35
  end
38
36
 
39
37
  def user_id_in_token?
40
- http_token && auth_token && auth_token[:user_id].to_i && jti_matches?
38
+ http_token && auth_token
41
39
  end
42
40
 
43
41
  def user_reset_token_in_params?
44
42
  params[:reset_password_token]
45
43
  end
44
+
45
+ def jwt
46
+ JsonWebToken.new
47
+ end
46
48
  end
@@ -29,11 +29,12 @@ class Api::V1::AuthenticationController < Api::BaseController
29
29
 
30
30
  iat = Time.now.to_i
31
31
  exp = Time.now.to_i + 24 * 3600
32
+
32
33
  {
33
- token: JsonWebToken.encode({ user_id: user.id,
34
- jti: user.jti,
35
- iat: iat,
36
- exp: exp })
34
+ token: jwt.encode({ user_id: user.id,
35
+ jti: user.jti,
36
+ iat: iat,
37
+ exp: exp })
37
38
  }
38
39
  end
39
40
  end
@@ -11,15 +11,14 @@ class Api::V1::PasswordsController < Api::BaseController
11
11
  @user = User.find_by(email: password_params[:email])
12
12
  if @user.nil?
13
13
  render json: { message: 'email not found' }, status: :not_found
14
+ elsif @user.update(
15
+ reset_password_token: SecureRandom.uuid,
16
+ reset_password_sent_at: Time.now
17
+ )
18
+ JwtMailer.reset_password(@user.id, @user.reset_password_token).deliver
19
+ render json: { message: 'reset password instructions sent' }, status: :ok
14
20
  else
15
- @user.reset_password_token = SecureRandom.uuid
16
- @user.reset_password_sent_at = Time.now
17
- if @user.save
18
- JwtMailer.reset_password(@user.id, @user.reset_password_token).deliver
19
- render json: { message: 'reset password instructions sent' }, status: :ok
20
- else
21
- render json: { message: @user.errors }, status: :not_found
22
- end
21
+ render json: { message: @user.errors }, status: :not_found
23
22
  end
24
23
  end
25
24
 
@@ -27,25 +26,22 @@ class Api::V1::PasswordsController < Api::BaseController
27
26
  # with a token in the params, if a succesful response is received, the client can
28
27
  # store the newly issued JWT and redirect the user to the password reset form
29
28
  def verify
30
- @user = User.where(reset_password_token: params[:token]).first
29
+ @user = User.find_by(reset_password_token: params[:token])
31
30
  if @user.nil?
32
31
  render json: { message: 'reset password token not found' }, status: :not_found
33
- elsif @user.reset_password_sent_at < 1.hour.ago
32
+ elsif @user.reset_password_sent_at < 10.minutes.ago
34
33
  render json: { message: 'reset password token has expired' }, status: :not_found
35
34
  else
36
- @user.reset_password_token = nil
37
- @user.reset_password_sent_at = nil
38
- @user.jti = SecureRandom.uuid
39
- @user.save
40
-
41
- iat = Time.now.to_i
42
- exp = Time.now.to_i + 10 * 60
43
-
35
+ @user.update!(
36
+ reset_password_token: nil,
37
+ reset_password_sent_at: nil,
38
+ jti: SecureRandom.uuid
39
+ )
44
40
  render json: {
45
41
  token: JsonWebToken.encode({ user_id: @user.id,
46
42
  jti: @user.jti,
47
- iat: iat,
48
- exp: exp })
43
+ iat: Time.now.to_i,
44
+ exp: Time.now.to_i + 10 * 60 })
49
45
  }, status: :ok
50
46
  end
51
47
  end
@@ -3,6 +3,7 @@
3
3
  # User controller
4
4
  class Api::V1::UsersController < Api::BaseController
5
5
  skip_before_action :authenticate_request!, only: %i[create]
6
+
6
7
  def create
7
8
  unless user_params[:password] == user_params[:password_confirmation]
8
9
  return render json: { message: "passwords don't match" }, status: :unprocessable_entity
@@ -1,11 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ # JSON Web Token class
1
4
  class JsonWebToken
2
- def self.encode(payload)
3
- JWT.encode(payload, Rails.application.secrets.secret_key_base)
5
+ def initialize(key = Rails.application.credentials[:secret_key_base], algorithm = 'HS256')
6
+ @key = key
7
+ @algorithm = algorithm
8
+ end
9
+
10
+ def encode(payload)
11
+ JWT.encode(payload, @key, @algorithm)
4
12
  end
5
13
 
6
- def self.decode(token)
7
- HashWithIndifferentAccess.new(JWT.decode(token, Rails.application.secrets.secret_key_base)[0])
8
- rescue StandardError
9
- nil
14
+ def decode(token)
15
+ JWT.decode(token, @key, @algorithm)
10
16
  end
11
17
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module JwtApi
4
- VERSION = "0.1.0"
4
+ VERSION = '0.1.1'
5
5
  end
data/lib/jwt_api.rb CHANGED
@@ -2,32 +2,3 @@
2
2
 
3
3
  require 'jwt'
4
4
  require_relative 'jwt_api/version'
5
-
6
- module JwtApi
7
- class Jwt
8
- def initialize(key, algorithm = 'HS256')
9
- @key = key
10
- @algorithm = algorithm
11
- end
12
-
13
- def encode(payload)
14
- JWT.encode(payload, @key, @algorithm)
15
- end
16
-
17
- def decode(token)
18
- JWT.decode(token, @key, @algorithm)
19
- end
20
- end
21
- end
22
-
23
- class JsonWebToken
24
- def self.encode(payload)
25
- JWT.encode(payload, Rails.application.secrets.secret_key_base)
26
- end
27
-
28
- def self.decode(token)
29
- HashWithIndifferentAccess.new(JWT.decode(token, Rails.application.secrets.secret_key_base)[0])
30
- rescue StandardError
31
- nil
32
- end
33
- end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jwt_api
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Leo Policastro
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-08-29 00:00:00.000000000 Z
11
+ date: 2022-02-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: jwt
@@ -48,6 +48,7 @@ files:
48
48
  - Rakefile
49
49
  - bin/console
50
50
  - bin/setup
51
+ - jwt_api-0.1.0.gem
51
52
  - jwt_api.gemspec
52
53
  - lib/generators/jwt_api/setup_generator.rb
53
54
  - lib/generators/jwt_api/templates/api/base_controller.rb
@@ -83,7 +84,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
83
84
  - !ruby/object:Gem::Version
84
85
  version: '0'
85
86
  requirements: []
86
- rubygems_version: 3.2.22
87
+ rubygems_version: 3.3.3
87
88
  signing_key:
88
89
  specification_version: 4
89
90
  summary: Write a short summary, because RubyGems requires one.