devise-passwordless 0.7.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -20,28 +20,19 @@ module Devise
20
20
  end
21
21
 
22
22
  def authenticate!
23
+ resource_class = mapping.to
24
+
23
25
  begin
24
- data = decode_passwordless_token
25
- rescue Devise::Passwordless::LoginToken::InvalidOrExpiredTokenError
26
+ resource, extra = resource_class.decode_passwordless_token(token, resource_class)
27
+ rescue Devise::Passwordless::InvalidOrExpiredTokenError
26
28
  fail!(:magic_link_invalid)
27
29
  return
28
30
  end
29
31
 
30
- resource = mapping.to.find_by(id: data["data"]["resource"]["key"])
31
-
32
- if resource && Devise.passwordless_expire_old_tokens_on_sign_in
33
- if (last_login = resource.try(:current_sign_in_at))
34
- token_created_at = ActiveSupport::TimeZone["UTC"].at(data["created_at"])
35
- if token_created_at < last_login
36
- fail!(:magic_link_invalid)
37
- return
38
- end
39
- end
40
- end
41
-
42
32
  if validate(resource)
43
33
  remember_me(resource)
44
34
  resource.after_magic_link_authentication
35
+ env['warden.magic_link_extra'] = extra.fetch('data', {}).delete('extra')
45
36
  success!(resource)
46
37
  else
47
38
  fail!(:magic_link_invalid)
@@ -50,10 +41,6 @@ module Devise
50
41
 
51
42
  private
52
43
 
53
- def decode_passwordless_token
54
- Devise::Passwordless::LoginToken.decode(self.token)
55
- end
56
-
57
44
  # Sets the authentication hash and the token from params_auth_hash or http_auth_hash.
58
45
  def with_authentication_hash(auth_type, auth_values)
59
46
  self.authentication_hash, self.authentication_type = {}, auth_type
@@ -67,10 +54,3 @@ module Devise
67
54
  end
68
55
 
69
56
  Warden::Strategies.add(:magic_link_authenticatable, Devise::Strategies::MagicLinkAuthenticatable)
70
-
71
- Devise.add_module(:magic_link_authenticatable, {
72
- strategy: true,
73
- controller: :sessions,
74
- route: :session,
75
- model: "devise/models/magic_link_authenticatable",
76
- })
@@ -11,23 +11,19 @@ module Devise::Passwordless
11
11
  File.dirname(__FILE__)
12
12
  end
13
13
 
14
- def create_sessions_controller
15
- template "sessions_controller.rb.erb", "app/controllers/devise/passwordless/sessions_controller.rb"
16
- end
17
-
18
- def create_magic_links_controller
19
- template "magic_links_controller.rb.erb", "app/controllers/devise/passwordless/magic_links_controller.rb"
20
- end
21
-
22
14
  def update_devise_initializer
23
15
  inject_into_file 'config/initializers/devise.rb', before: /^end$/ do <<~'CONFIG'.indent(2)
24
16
 
25
17
  # ==> Configuration for :magic_link_authenticatable
26
18
 
27
- # Need to use a custom Devise mailer in order to send magic links
28
- require "devise/passwordless/mailer"
19
+ # Need to use a custom Devise mailer in order to send magic links.
20
+ # If you're already using a custom mailer just have it inherit from
21
+ # Devise::Passwordless::Mailer instead of Devise::Mailer
29
22
  config.mailer = "Devise::Passwordless::Mailer"
30
23
 
24
+ # Which algorithm to use for tokenizing magic links. See README for descriptions
25
+ config.passwordless_tokenizer = "SignedGlobalIDTokenizer"
26
+
31
27
  # Time period after a magic login link is sent out that it will be valid for.
32
28
  # config.passwordless_login_within = 20.minutes
33
29
 
@@ -51,7 +47,7 @@ module Devise::Passwordless
51
47
 
52
48
  <p>You can login using the link below:</p>
53
49
 
54
- <p><%= link_to "Log in to my account", send("#{@scope_name.to_s.pluralize}_magic_link_url", Hash[@scope_name, {email: @resource.email, token: @token, remember_me: @remember_me}]) %></p>
50
+ <p><%= link_to "Log in to my account", magic_link_url(@resource, @scope_name => {email: @resource.email, token: @token, remember_me: @remember_me}) %></p>
55
51
 
56
52
  <p>Note that the link will expire in <%= Devise.passwordless_login_within.inspect %>.</p>
57
53
  FILE
@@ -75,6 +71,7 @@ module Devise::Passwordless
75
71
  passwordless: {
76
72
  not_found_in_database: "Could not find a user for that email address",
77
73
  magic_link_sent: "A login link has been sent to your email address. Please follow the link to log in to your account.",
74
+ magic_link_sent_paranoid: "If your account exists, you will receive an email with a login link. Please follow the link to log in to your account.",
78
75
  },
79
76
  failure: {
80
77
  magic_link_invalid: "Invalid or expired login link.",
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: devise-passwordless
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Abe Voelker
8
8
  autorequire:
9
- bindir: exe
9
+ bindir: bin
10
10
  cert_chain: []
11
- date: 2022-03-06 00:00:00.000000000 Z
11
+ date: 2023-09-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: devise
@@ -24,6 +24,34 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: globalid
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: timecop
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
27
55
  description:
28
56
  email:
29
57
  - _@abevoelker.com
@@ -31,33 +59,34 @@ executables: []
31
59
  extensions: []
32
60
  extra_rdoc_files: []
33
61
  files:
34
- - ".github/workflows/test.yml"
35
- - ".gitignore"
36
- - ".rspec"
37
- - ".travis.yml"
38
- - Gemfile
62
+ - CHANGELOG.md
39
63
  - LICENSE.txt
40
64
  - README.md
41
- - Rakefile
42
- - bin/console
43
- - bin/setup
44
- - devise-passwordless.gemspec
65
+ - UPGRADING.md
66
+ - app/controllers/devise/magic_links_controller.rb
67
+ - app/controllers/devise/passwordless/sessions_controller.rb
68
+ - app/mailers/devise/passwordless/mailer.rb
69
+ - lib/devise/hooks/magic_link_authenticatable.rb
45
70
  - lib/devise/models/magic_link_authenticatable.rb
71
+ - lib/devise/monkeypatch.rb
46
72
  - lib/devise/passwordless.rb
47
73
  - lib/devise/passwordless/login_token.rb
48
- - lib/devise/passwordless/mailer.rb
74
+ - lib/devise/passwordless/rails.rb
75
+ - lib/devise/passwordless/routing.rb
76
+ - lib/devise/passwordless/tokenizers/message_encryptor_tokenizer.rb
77
+ - lib/devise/passwordless/tokenizers/signed_global_id_tokenizer.rb
49
78
  - lib/devise/passwordless/version.rb
50
79
  - lib/devise/strategies/magic_link_authenticatable.rb
51
80
  - lib/generators/devise/passwordless/install_generator.rb
52
- - lib/generators/devise/passwordless/templates/magic_links_controller.rb.erb
53
- - lib/generators/devise/passwordless/templates/sessions_controller.rb.erb
54
81
  homepage: https://github.com/abevoelker/devise-passwordless
55
82
  licenses:
56
83
  - MIT
57
84
  metadata:
58
85
  homepage_uri: https://github.com/abevoelker/devise-passwordless
59
86
  source_code_uri: https://github.com/abevoelker/devise-passwordless
60
- post_install_message:
87
+ post_install_message: "\n Devise Passwordless v1.0 introduces major, backwards-incompatible
88
+ changes!\n Please see https://github.com/abevoelker/devise-passwordless/blob/master/UPGRADING.md\n
89
+ \ for a guide on upgrading, or CHANGELOG.md for a list of changes.\n "
61
90
  rdoc_options: []
62
91
  require_paths:
63
92
  - lib
@@ -72,7 +101,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
72
101
  - !ruby/object:Gem::Version
73
102
  version: '0'
74
103
  requirements: []
75
- rubygems_version: 3.1.6
104
+ rubygems_version: 3.4.10
76
105
  signing_key:
77
106
  specification_version: 4
78
107
  summary: Passwordless (email-only) login strategy for Devise
@@ -1,45 +0,0 @@
1
- name: test
2
-
3
- on:
4
- push:
5
- branches: [ master ]
6
- pull_request:
7
- branches: [ master ]
8
-
9
- jobs:
10
- test:
11
- runs-on: ubuntu-latest
12
- strategy:
13
- matrix:
14
- ruby-version:
15
- - 3.0
16
- - 2.7
17
- - 2.6
18
- - 2.5
19
- gemfile:
20
- - Gemfile-rails-7
21
- - Gemfile-rails-6.1
22
- - Gemfile-rails-6.0
23
- exclude:
24
- # Rails 7 requires Ruby 2.7+
25
- - ruby-version: 2.5
26
- gemfile: Gemfile-rails-7
27
- - ruby-version: 2.6
28
- gemfile: Gemfile-rails-7
29
- steps:
30
- - uses: actions/checkout@v2
31
- - name: Set up Ruby ${{ matrix.ruby-version }}
32
- uses: ruby/setup-ruby@477b21f02be01bcb8030d50f37cfec92bfa615b6
33
- with:
34
- ruby-version: ${{ matrix.ruby-version }}
35
- - name: Run gem tests
36
- run: |
37
- bundle
38
- bundle exec rake
39
- - name: Run Rails dummy app tests
40
- working-directory: ./spec/dummy_app
41
- env:
42
- BUNDLE_GEMFILE: gemfiles/${{ matrix.gemfile }}
43
- run: |
44
- bundle
45
- bundle exec rake
data/.gitignore DELETED
@@ -1,16 +0,0 @@
1
- /.bundle/
2
- /.yardoc
3
- /_yardoc/
4
- /coverage/
5
- /doc/
6
- /pkg/
7
- /spec/reports/
8
- /spec/tmp
9
- /tmp/
10
- Gemfile.lock
11
- Gemfile*.lock
12
-
13
- # rspec failure tracking
14
- .rspec_status
15
-
16
- .ruby-version
data/.rspec DELETED
@@ -1,4 +0,0 @@
1
- --format documentation
2
- --color
3
- --require spec_helper
4
- --exclude-pattern "spec/dummy_app/**/**"
data/.travis.yml DELETED
@@ -1,7 +0,0 @@
1
- ---
2
- sudo: false
3
- language: ruby
4
- cache: bundler
5
- rvm:
6
- - 2.6.2
7
- before_install: gem install bundler -v 1.17.2
data/Gemfile DELETED
@@ -1,13 +0,0 @@
1
- source "https://rubygems.org"
2
-
3
- git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
4
-
5
- # Specify your gem's dependencies in devise-passwordless.gemspec
6
- gemspec
7
-
8
- gem "rake", "~> 10.0"
9
-
10
- group :test do
11
- gem "rspec", "~> 3.0"
12
- gem "generator_spec"
13
- end
data/Rakefile DELETED
@@ -1,6 +0,0 @@
1
- require "bundler/gem_tasks"
2
- require "rspec/core/rake_task"
3
-
4
- RSpec::Core::RakeTask.new(:spec)
5
-
6
- task :default => :spec
data/bin/console DELETED
@@ -1,14 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require "bundler/setup"
4
- require "devise/passwordless"
5
-
6
- # You can add fixtures and/or initialization code here to make experimenting
7
- # with your gem easier. You can also use a different console, if you like.
8
-
9
- # (If you use this, don't forget to add pry to your Gemfile!)
10
- # require "pry"
11
- # Pry.start
12
-
13
- require "irb"
14
- IRB.start(__FILE__)
data/bin/setup DELETED
@@ -1,8 +0,0 @@
1
- #!/usr/bin/env bash
2
- set -euo pipefail
3
- IFS=$'\n\t'
4
- set -vx
5
-
6
- bundle install
7
-
8
- # Do any other automated setup that you need to do here
@@ -1,41 +0,0 @@
1
-
2
- lib = File.expand_path("../lib", __FILE__)
3
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require "devise/passwordless/version"
5
-
6
- Gem::Specification.new do |spec|
7
- spec.name = "devise-passwordless"
8
- spec.version = Devise::Passwordless::VERSION
9
- spec.authors = ["Abe Voelker"]
10
- spec.email = ["_@abevoelker.com"]
11
-
12
- spec.summary = %q{Passwordless (email-only) login strategy for Devise}
13
- #spec.description = %q{TODO: Write a longer description or delete this line.}
14
- spec.homepage = "https://github.com/abevoelker/devise-passwordless"
15
- spec.license = "MIT"
16
-
17
- # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
18
- # to allow pushing to a single host or delete this section to allow pushing to any host.
19
- if spec.respond_to?(:metadata)
20
- #spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'"
21
-
22
- spec.metadata["homepage_uri"] = spec.homepage
23
- spec.metadata["source_code_uri"] = spec.homepage
24
- #spec.metadata["changelog_uri"] = "TODO: Put your gem's CHANGELOG.md URL here."
25
- else
26
- raise "RubyGems 2.0 or newer is required to protect against " \
27
- "public gem pushes."
28
- end
29
-
30
- # Specify which files should be added to the gem when it is released.
31
- # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
32
- spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
33
- `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
34
- end
35
- spec.bindir = "exe"
36
- spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
37
- spec.require_paths = ["lib"]
38
- spec.required_ruby_version = ">= 2.1.0"
39
-
40
- spec.add_dependency "devise"
41
- end
@@ -1,12 +0,0 @@
1
- # frozen_string_literal: true
2
- require "devise/mailer"
3
-
4
- module Devise::Passwordless
5
- class Mailer < Devise::Mailer
6
- def magic_link(record, token, remember_me, opts = {})
7
- @token = token
8
- @remember_me = remember_me
9
- devise_mail(record, :magic_link, opts)
10
- end
11
- end
12
- end
@@ -1,34 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- <% module_namespacing do -%>
4
- class Devise::Passwordless::SessionsController < Devise::SessionsController
5
- def create
6
- self.resource = resource_class.find_by(email: create_params[:email])
7
- if self.resource
8
- resource.send_magic_link(create_params[:remember_me])
9
- set_flash_message(:notice, :magic_link_sent, now: true)
10
- else
11
- set_flash_message(:alert, :not_found_in_database, now: true)
12
- end
13
-
14
- self.resource = resource_class.new(create_params)
15
- render :new
16
- end
17
-
18
- protected
19
-
20
- def translation_scope
21
- if action_name == "create"
22
- "devise.passwordless"
23
- else
24
- super
25
- end
26
- end
27
-
28
- private
29
-
30
- def create_params
31
- resource_params.permit(:email, :remember_me)
32
- end
33
- end
34
- <% end -%>