jwt-auth 3.0.0 → 3.0.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.
Files changed (82) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +48 -19
  3. data/.travis.yml +11 -0
  4. data/README.md +1 -1
  5. data/jwt-auth.gemspec +24 -21
  6. data/lib/jwt/auth/authentication.rb +3 -3
  7. data/lib/jwt/auth/token.rb +14 -3
  8. data/lib/jwt/auth/version.rb +1 -1
  9. data/spec/authentication_spec.rb +95 -0
  10. data/spec/configuration_spec.rb +1 -1
  11. data/spec/dummy/.gitignore +41 -0
  12. data/spec/dummy/Rakefile +6 -0
  13. data/spec/dummy/app/assets/config/manifest.js +4 -0
  14. data/spec/dummy/app/assets/images/.keep +0 -0
  15. data/spec/dummy/app/assets/javascripts/application.js +13 -0
  16. data/spec/dummy/app/assets/javascripts/cable.js +13 -0
  17. data/spec/dummy/app/assets/javascripts/channels/.keep +0 -0
  18. data/spec/dummy/app/assets/stylesheets/application.css +15 -0
  19. data/spec/dummy/app/channels/application_cable/channel.rb +4 -0
  20. data/spec/dummy/app/channels/application_cable/connection.rb +4 -0
  21. data/spec/dummy/app/controllers/application_controller.rb +13 -0
  22. data/spec/dummy/app/controllers/authentication_controller.rb +15 -0
  23. data/spec/dummy/app/controllers/concerns/.keep +0 -0
  24. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  25. data/spec/dummy/app/helpers/authentication_helper.rb +2 -0
  26. data/spec/dummy/app/jobs/application_job.rb +2 -0
  27. data/spec/dummy/app/mailers/application_mailer.rb +4 -0
  28. data/spec/dummy/app/models/application_record.rb +3 -0
  29. data/spec/dummy/app/models/concerns/.keep +0 -0
  30. data/spec/dummy/app/models/user.rb +14 -0
  31. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  32. data/spec/dummy/app/views/layouts/mailer.html.erb +13 -0
  33. data/spec/dummy/app/views/layouts/mailer.text.erb +1 -0
  34. data/spec/dummy/bin/bundle +3 -0
  35. data/spec/dummy/bin/rails +4 -0
  36. data/spec/dummy/bin/rake +4 -0
  37. data/spec/dummy/bin/setup +38 -0
  38. data/spec/dummy/bin/update +29 -0
  39. data/spec/dummy/bin/yarn +11 -0
  40. data/spec/dummy/config.ru +5 -0
  41. data/spec/dummy/config/application.rb +18 -0
  42. data/spec/dummy/config/boot.rb +5 -0
  43. data/spec/dummy/config/cable.yml +10 -0
  44. data/spec/dummy/config/database.yml +25 -0
  45. data/spec/dummy/config/environment.rb +5 -0
  46. data/spec/dummy/config/environments/development.rb +54 -0
  47. data/spec/dummy/config/environments/production.rb +91 -0
  48. data/spec/dummy/config/environments/test.rb +42 -0
  49. data/spec/dummy/config/initializers/application_controller_renderer.rb +6 -0
  50. data/spec/dummy/config/initializers/assets.rb +14 -0
  51. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  52. data/spec/dummy/config/initializers/cookies_serializer.rb +5 -0
  53. data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  54. data/spec/dummy/config/initializers/inflections.rb +16 -0
  55. data/spec/dummy/config/initializers/jwt_auth.rb +11 -0
  56. data/spec/dummy/config/initializers/mime_types.rb +4 -0
  57. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  58. data/spec/dummy/config/locales/en.yml +33 -0
  59. data/spec/dummy/config/puma.rb +56 -0
  60. data/spec/dummy/config/routes.rb +6 -0
  61. data/spec/dummy/config/secrets.yml +32 -0
  62. data/spec/dummy/config/spring.rb +6 -0
  63. data/spec/dummy/db/migrate/20170726110751_create_users.rb +9 -0
  64. data/spec/dummy/db/migrate/20170726110825_add_token_version_to_user.rb +5 -0
  65. data/spec/dummy/db/migrate/20170726112117_add_activated_to_user.rb +5 -0
  66. data/spec/dummy/db/schema.rb +23 -0
  67. data/spec/dummy/lib/assets/.keep +0 -0
  68. data/spec/dummy/log/.keep +0 -0
  69. data/spec/dummy/package.json +5 -0
  70. data/spec/dummy/public/404.html +67 -0
  71. data/spec/dummy/public/422.html +67 -0
  72. data/spec/dummy/public/500.html +66 -0
  73. data/spec/dummy/public/apple-touch-icon-precomposed.png +0 -0
  74. data/spec/dummy/public/apple-touch-icon.png +0 -0
  75. data/spec/dummy/public/favicon.ico +0 -0
  76. data/spec/dummy/tmp/.keep +0 -0
  77. data/spec/rails_helper.rb +50 -0
  78. data/spec/spec_helper.rb +4 -1
  79. data/spec/support/.keep +0 -0
  80. data/spec/token_spec.rb +76 -4
  81. metadata +196 -18
  82. data/spec/support/dummy_user.rb +0 -16
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4fc903bec961f43790b39851ed465e98ee4db262
4
- data.tar.gz: 2c54dc88944789086ec0ef2cfb11f33b3ec63520
3
+ metadata.gz: 7cd012fc046f4777af5d9ee5f6265f5ca2d62af9
4
+ data.tar.gz: 9170ff259b31aa1867b40da3572db62b4b1af852
5
5
  SHA512:
6
- metadata.gz: 6caaeac87553b3fb5fc3ab08e7c0806cb01ba40cac74e8b11bf739517383687289dd9f157a22b81b9571029c58ff04cc8f499abb6e0059a2f32016d5c05aa13d
7
- data.tar.gz: 89da2604d876f84c21836acfb6cf11e47c3d542a01514ee2d2d6d4b653c5f081f60ce670e1dfb67a3f532f8d3f9ae803af65e9bd3f65b1a19105cee23b62f8e4
6
+ metadata.gz: cee44e1a66ed06d4ecb6298542b45b13c72a2806c271805c2e8772dcab5b755ad4f9cf9c862c8f507a511744fa52c28e600c458b48ef50b555ca6ae1e946afb1
7
+ data.tar.gz: b34a80b8d6bb0f0cf068b4505101edbc9030f96bcccf3bd5b5bcb5ffe55b7e7fd77726177dbb2ac68b3fe1981edf2c68ecdd5a04a54d7b2ff2d2ab9dbb4c8eda
data/.gitignore CHANGED
@@ -1,25 +1,54 @@
1
1
  *.gem
2
2
  *.rbc
3
- .bundle
4
- .config
5
- .yardoc
3
+ /.config
4
+ /coverage/
5
+ /InstalledFiles
6
+ /pkg/
7
+ /spec/reports/
8
+ /spec/examples.txt
9
+ /test/tmp/
10
+ /test/version_tmp/
11
+ /tmp/
12
+ .byebug_history
13
+
14
+ # Used by dotenv library to load environment variables.
15
+ # .env
16
+
17
+ ## Specific to RubyMotion:
18
+ .dat*
19
+ .repl_history
20
+ build/
21
+ *.bridgesupport
22
+ build-iPhoneOS/
23
+ build-iPhoneSimulator/
24
+
25
+ ## Specific to RubyMotion (use of CocoaPods):
26
+ #
27
+ # We recommend against adding the Pods directory to your .gitignore. However
28
+ # you should judge for yourself, the pros and cons are mentioned at:
29
+ # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
30
+ #
31
+ # vendor/Pods/
32
+
33
+ ## Documentation cache and generated files:
34
+ /.yardoc/
35
+ /_yardoc/
36
+ /doc/
37
+ /rdoc/
38
+
39
+ ## Environment normalization:
40
+ /.bundle/
41
+ /vendor/bundle
42
+ /lib/bundler/man/
43
+
44
+ # for a library or gem, you might want to ignore these files since the code is
45
+ # intended to run in multiple environments; otherwise, check them in:
6
46
  Gemfile.lock
7
- InstalledFiles
8
- _yardoc
9
- coverage
10
- doc/
11
- lib/bundler/man
12
- pkg
13
- rdoc
14
- spec/reports
15
- test/tmp
16
- test/version_tmp
17
- tmp
18
- *.bundle
19
- *.so
20
- *.o
21
- *.a
22
- mkmf.log
23
47
  .ruby-version
24
48
  .ruby-gemset
49
+
50
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
51
+ .rvmrc
52
+
53
+ # IDE files
25
54
  .idea
@@ -0,0 +1,11 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.4.0
4
+ cache:
5
+ bundler: true
6
+ env:
7
+ - RAILS_ENV=test CI=true TRAVIS=true
8
+ install:
9
+ - bundle install
10
+ script:
11
+ - bundle exec rspec
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # JWT::Auth
1
+ # JWT::Auth [![Travis](https://travis-ci.org/floriandejonckheere/jwt-auth.svg?branch=master)](https://travis-ci.org/floriandejonckheere/jwt-auth) [![Coverage Status](https://coveralls.io/repos/github/floriandejonckheere/jwt-auth/badge.svg)](https://coveralls.io/github/floriandejonckheere/jwt-auth)
2
2
 
3
3
  JWT-based authentication middleware for Rails API without Devise
4
4
 
@@ -6,28 +6,31 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
6
6
 
7
7
  require 'jwt/auth/version'
8
8
 
9
- Gem::Specification.new do |spec|
10
- spec.name = 'jwt-auth'
11
- spec.version = JWT::Auth::VERSION
12
- spec.authors = ['Florian Dejonckheere']
13
- spec.email = ['florian@floriandejonckheere.be']
14
- spec.summary = 'JWT-based authentication for Rails API without Devise'
15
- spec.description = 'Authentication middleware for Rails API that uses JWTs, without depending on Devise'
16
- spec.homepage = 'https://github.com/floriandejonckheere/jwt-auth'
17
- spec.license = 'MIT'
9
+ Gem::Specification.new do |gem|
10
+ gem.name = 'jwt-auth'
11
+ gem.version = JWT::Auth::VERSION
12
+ gem.authors = ['Florian Dejonckheere']
13
+ gem.email = ['florian@floriandejonckheere.be']
14
+ gem.summary = 'JWT-based authentication for Rails API'
15
+ gem.description = 'Authentication middleware for Rails API that uses JWTs'
16
+ gem.homepage = 'https://github.com/floriandejonckheere/jwt-auth'
17
+ gem.license = 'MIT'
18
18
 
19
- spec.files = `git ls-files -z`.split("\x0")
20
- spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
21
- spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
22
- spec.require_paths = ['lib']
19
+ gem.files = `git ls-files -z`.split("\x0")
20
+ gem.executables = gem.files.grep(%r{^bin/}) { |f| File.basename(f) }
21
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
22
+ gem.require_paths = ['lib']
23
23
 
24
- spec.add_dependency 'jwt', '~> 1.5'
25
- spec.add_dependency 'rails', '~> 5.0'
24
+ gem.add_runtime_dependency 'jwt', '~> 1.5'
25
+ gem.add_runtime_dependency 'rails', '~> 5.1'
26
26
 
27
- spec.add_development_dependency 'bundler', '~> 1.14'
28
- spec.add_development_dependency 'rubocop', '~> 0.48'
29
- spec.add_development_dependency 'rake', '~> 12.0'
30
- spec.add_development_dependency 'rspec', '~> 3.5'
31
- spec.add_development_dependency 'rspec-rails', '~> 3.5'
32
- spec.add_development_dependency 'byebug'
27
+ gem.add_development_dependency 'bundler', '~> 1.15'
28
+ gem.add_development_dependency 'rubocop', '~> 0.49'
29
+ gem.add_development_dependency 'rake', '~> 12.0'
30
+ gem.add_development_dependency 'rspec', '~> 3.6'
31
+ gem.add_development_dependency 'rspec-rails', '~> 3.6'
32
+ gem.add_development_dependency 'rdoc', '~> 5.1'
33
+ gem.add_development_dependency 'coveralls', '~> 0.8'
34
+ gem.add_development_dependency 'byebug'
35
+ gem.add_development_dependency 'sqlite3'
33
36
  end
@@ -12,21 +12,21 @@ module JWT
12
12
  # Current user helper
13
13
  #
14
14
  def current_user
15
- jwt&.subject
15
+ jwt && jwt.subject
16
16
  end
17
17
 
18
18
  ##
19
19
  # Authenticate a request
20
20
  #
21
21
  def authenticate_user
22
- raise JWT::Auth::UnauthorizedError unless jwt&.valid?
22
+ raise JWT::Auth::UnauthorizedError unless jwt && jwt.valid?
23
23
  end
24
24
 
25
25
  ##
26
26
  # Add JWT header to response
27
27
  #
28
28
  def renew_token
29
- return unless jwt&.valid?
29
+ return unless jwt && jwt.valid?
30
30
  jwt.renew!
31
31
  response.headers['Authorization'] = "Bearer #{jwt.to_jwt}"
32
32
  end
@@ -13,11 +13,16 @@ module JWT
13
13
  attr_accessor :expiration, :subject, :token_version
14
14
 
15
15
  def valid?
16
+ # Reload subject to prevent caching the old token_version
17
+ subject && subject.reload
18
+
16
19
  return false if subject.nil? || expiration.nil? || token_version.nil?
17
20
  return false if Time.at(expiration).past?
18
21
  return false if token_version != subject.token_version
19
22
 
20
23
  true
24
+ rescue ActiveRecord::RecordNotFound
25
+ false
21
26
  end
22
27
 
23
28
  def renew!
@@ -42,14 +47,20 @@ module JWT
42
47
  end
43
48
 
44
49
  def self.from_token(token)
45
- payload = JWT.decode(token, JWT::Auth.secret).first
50
+ begin
51
+ payload = JWT.decode(token, JWT::Auth.secret).first
52
+ rescue JWT::ExpiredSignature
53
+ payload = {}
54
+ end
46
55
 
47
56
  token = JWT::Auth::Token.new
48
57
  token.expiration = payload['exp']
49
58
  token.token_version = payload['ver']
50
59
 
51
- find_method = JWT::Auth.model.respond_to?(:find_by_token) ? :find_by_token : :find_by
52
- token.subject = JWT::Auth.model.send find_method, :id => payload['sub'], :token_version => payload['ver']
60
+ if payload['sub']
61
+ find_method = JWT::Auth.model.respond_to?(:find_by_token) ? :find_by_token : :find_by
62
+ token.subject = JWT::Auth.model.send find_method, :id => payload['sub'], :token_version => payload['ver']
63
+ end
53
64
 
54
65
  token
55
66
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module JWT
4
4
  module Auth
5
- VERSION = '3.0.0'
5
+ VERSION = '3.0.1'
6
6
  end
7
7
  end
@@ -0,0 +1,95 @@
1
+ # frozen_string_listeral: true
2
+
3
+ require 'rails_helper'
4
+
5
+ RSpec.describe AuthenticationController, :type => :request do
6
+ let(:user) { User.create :activated => true }
7
+
8
+ let(:headers) do
9
+ {
10
+ 'Authorization' => "Bearer #{JWT::Auth::Token.from_user(user).to_jwt}"
11
+ }
12
+ end
13
+
14
+ describe 'GET /public' do
15
+ context 'activated user' do
16
+ it 'is accessible without token' do
17
+ get '/public'
18
+
19
+ expect(response.status).to eq 204
20
+ end
21
+
22
+ it 'is accessible with token' do
23
+ get '/public', :headers => headers
24
+
25
+ expect(response.status).to eq 204
26
+ end
27
+
28
+ it 'renews the token' do
29
+ get '/public', :headers => headers
30
+
31
+ jwt = response.headers['Authorization'].scan(/Bearer (.*)$/).flatten.last
32
+ token = JWT::Auth::Token.from_token jwt
33
+
34
+ expect(token).to be_valid
35
+ end
36
+ end
37
+
38
+ context 'disabled user' do
39
+ let(:user) { User.new }
40
+
41
+ it 'is accessible without token' do
42
+ get '/public'
43
+
44
+ expect(response.status).to eq 204
45
+ end
46
+
47
+ it 'is accessible with token' do
48
+ get '/public', :headers => headers
49
+
50
+ expect(response.status).to eq 204
51
+ end
52
+ end
53
+ end
54
+
55
+ describe 'GET /private' do
56
+ context 'activated user' do
57
+ it 'is not accessible without token' do
58
+ get '/private'
59
+
60
+ expect(response.status).to eq 401
61
+ end
62
+
63
+ it 'is accessible with token' do
64
+ get '/private', :headers => headers
65
+
66
+ expect(response.status).to eq 204
67
+ end
68
+
69
+ it 'renews the token' do
70
+ get '/private', :headers => headers
71
+
72
+ jwt = response.headers['Authorization'].scan(/Bearer (.*)$/).flatten.last
73
+ token = JWT::Auth::Token.from_token jwt
74
+
75
+ expect(token).to be_valid
76
+ end
77
+ end
78
+
79
+ context 'disabled user' do
80
+ let(:user) { User.new }
81
+
82
+ it 'is not accessible without token' do
83
+ get '/private'
84
+
85
+ expect(response.status).to eq 401
86
+ end
87
+
88
+ it 'is not accessible with token' do
89
+ get '/private', :headers => headers
90
+
91
+ expect(response.status).to eq 401
92
+ end
93
+ end
94
+ end
95
+ end
@@ -13,6 +13,6 @@ RSpec.describe JWT::Auth do
13
13
 
14
14
  expect(subject.token_lifetime).to eq 24.hours
15
15
  expect(subject.secret).to eq 'mysecret'
16
- expect(subject.model).to eq DummyUser
16
+ expect(subject.model).to eq User
17
17
  end
18
18
  end
@@ -0,0 +1,41 @@
1
+ # See https://help.github.com/articles/ignoring-files for more about ignoring files.
2
+ #
3
+ # If you find yourself ignoring temporary files generated by your text editor
4
+ # or operating system, you probably want to add a global ignore instead:
5
+ # git config --global core.excludesfile '~/.gitignore_global'
6
+
7
+ # Ignore bundler config.
8
+ /.bundle
9
+ /.gem
10
+
11
+ # Ignore the default SQLite database.
12
+ /db/*.sqlite3
13
+ /db/*.sqlite3-journal
14
+
15
+ # Ignore all logfiles and tempfiles.
16
+ /log/*
17
+ /tmp/*
18
+ !/log/.keep
19
+ !/tmp/.keep
20
+
21
+ # Ignore Byebug command history file.
22
+ .byebug_history
23
+
24
+ # IDE files
25
+ .idea
26
+
27
+ # Webpack files
28
+ node_modules
29
+ /client/public
30
+
31
+ # Private files
32
+ *.env
33
+ config/*.pem
34
+ config/*.pub
35
+
36
+ # Coverage report
37
+ coverage/
38
+
39
+ /.gem
40
+ /.vscode
41
+ .DS_Store
@@ -0,0 +1,6 @@
1
+ # Add your own tasks in files placed in lib/tasks ending in .rake,
2
+ # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
3
+
4
+ require_relative 'config/application'
5
+
6
+ Rails.application.load_tasks
@@ -0,0 +1,4 @@
1
+
2
+ //= link_tree ../images
3
+ //= link_directory ../javascripts .js
4
+ //= link_directory ../stylesheets .css
File without changes
@@ -0,0 +1,13 @@
1
+ // This is a manifest file that'll be compiled into application.js, which will include all the files
2
+ // listed below.
3
+ //
4
+ // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
5
+ // or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
6
+ //
7
+ // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
8
+ // compiled file. JavaScript code in this file should be added after the last require_* statement.
9
+ //
10
+ // Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
11
+ // about supported directives.
12
+ //
13
+ //= require_tree .
@@ -0,0 +1,13 @@
1
+ // Action Cable provides the framework to deal with WebSockets in Rails.
2
+ // You can generate new channels where WebSocket features live using the `rails generate channel` command.
3
+ //
4
+ //= require action_cable
5
+ //= require_self
6
+ //= require_tree ./channels
7
+
8
+ (function() {
9
+ this.App || (this.App = {});
10
+
11
+ App.cable = ActionCable.createConsumer();
12
+
13
+ }).call(this);
@@ -0,0 +1,15 @@
1
+ /*
2
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
3
+ * listed below.
4
+ *
5
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
+ * or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
7
+ *
8
+ * You're free to add application-wide styles to this file and they'll appear at the bottom of the
9
+ * compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
10
+ * files in this directory. Styles in this file should be added after the last require_* statement.
11
+ * It is generally better to create a new file per style scope.
12
+ *
13
+ *= require_tree .
14
+ *= require_self
15
+ */
@@ -0,0 +1,4 @@
1
+ module ApplicationCable
2
+ class Channel < ActionCable::Channel::Base
3
+ end
4
+ end