magic-link 0.1.0 → 1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6d9cdcff5bac8ba5789ac41f1b297408a4fba83f063d3afbb3bd585549996be9
4
- data.tar.gz: 6e7cf401d907dcdb65421a2fac94084b1749b3bd84e5d0e0ac334e82738ef96d
3
+ metadata.gz: 4702207f1e6738652b3afb874370dedda68060c8d9c8ae9eb083eba8acec3912
4
+ data.tar.gz: 7c4e9bf8c79ef5fd2bb426b8c6f5bcbbc8e5f31db27345f81719d7819388928f
5
5
  SHA512:
6
- metadata.gz: 58db75b1fed54635bdc015e83a7f170c5c3193b054d94a35270a58f269045925c5a26004edc7ce5f9218057a72bec54d4d3095bf66aab19fce6b9ff1801a55df
7
- data.tar.gz: b06b4740c460825a17e969ff4cc0d9272463c028dd6b855f49d2dff8767a6e62277601065416cc6a3d55d1b9512172d99b3d1cb6517198a1a6d987c49a028b38
6
+ metadata.gz: 1a7f9f1c88d957ff6e8b1975c6734af4fa42aff3d8b2700c0086353f3045364aa1c7d219db4b2cdb84a97e9d981966126277b28b65341e5ba9e9e8478ea53158
7
+ data.tar.gz: 689167a5bc00421dc3929edb49b447c8957467b0adb448e1c86ab736e628b9a5bb5de53b0422ae055d654da7df8aeb1c0b7af29885ace08a5032d673abd4217e
data/README.md CHANGED
@@ -19,7 +19,7 @@ mount the engine
19
19
  mount Magic::Link::Engine, at: '/'
20
20
  ```
21
21
 
22
- Now users can visit `/magic_links/new` to enter their email and have a sign in
22
+ Now users can visit `/magic_links/new` (which you can link to with `magic_link.new_magic_link_path`) to enter their email and have a sign in
23
23
  link sent to them via email. Tokens are cleared after use and expire after the
24
24
  configured number of hours
25
25
 
@@ -1,6 +1,7 @@
1
1
  module Magic
2
2
  module Link
3
3
  class MagicLinksController < ::ApplicationController
4
+ skip_before_action :authenticate_user!, :raise => false
4
5
  before_action :check_user, only: :new
5
6
 
6
7
  def new
@@ -13,6 +14,26 @@ module Magic
13
14
  redirect_to main_app.root_path, notice: "Check your email for a sign in link!"
14
15
  end
15
16
 
17
+ def authenticate
18
+ email = params[:email].presence
19
+ token = params[:sign_in_token].presence
20
+ user = email && token && Magic::Link.user_class.find_by(email: email)
21
+
22
+ # TODO: Handle a different user trying to sign in
23
+ if token && send("#{Magic::Link.user_class.name.underscore}_signed_in?")
24
+ flash[:alert] = "You are already signed in"
25
+ redirect_to main_app.send(Magic::Link.after_sign_in_path)
26
+ elsif user && token_matches?(user) && token_not_expired?(user)
27
+ flash[:notice] = "You have signed in successfully"
28
+ user.update_columns(sign_in_token: nil, sign_in_token_sent_at: nil)
29
+ sign_in user
30
+ redirect_to main_app.send(Magic::Link.after_sign_in_path)
31
+ elsif email && token
32
+ flash[:alert] = "Your sign in token is invalid"
33
+ redirect_to magic_link.new_magic_link_path
34
+ end
35
+ end
36
+
16
37
  private
17
38
 
18
39
  def check_user
@@ -21,6 +42,17 @@ module Magic
21
42
  end
22
43
  end
23
44
 
45
+ def token_matches?(user)
46
+ Devise.secure_compare(
47
+ user.sign_in_token,
48
+ Devise.token_generator.digest(Magic::Link.user_class, :sign_in_token, params[:sign_in_token])
49
+ )
50
+ end
51
+
52
+ def token_not_expired?(user)
53
+ user.sign_in_token_sent_at >= Magic::Link.token_expiration_hours.hours.ago
54
+ end
55
+
24
56
  def permitted_params
25
57
  params.fetch(:magic_link, {}).permit(:email)
26
58
  end
@@ -1,5 +1,5 @@
1
1
  <p>Hey there! Here is your sign in link (you can only use it once):</p>
2
2
 
3
- <p><%= link_to "Sign In", main_app.root_url(email: @email, sign_in_token: @token) %></p>
3
+ <p><%= link_to "Sign In", magic_link.authenticate_url(email: @email, sign_in_token: @token) %></p>
4
4
 
5
5
  <p>Thanks!</p>
@@ -1,5 +1,5 @@
1
1
  Hey there! Here is your sign in link (you can only use it once):
2
2
 
3
- <%= main_app.root_url(email: @email, sign_in_token: @token) %>
3
+ <%= magic_link.authenticate_url(email: @email, sign_in_token: @token) %>
4
4
 
5
5
  Thanks!
@@ -1,7 +1,11 @@
1
1
  <div class="row">
2
2
  <div class="col-md-6 offset-md-3">
3
- <%= simple_form_for @magic_link do |f| %>
4
- <%= f.input :email, label: "Enter your email", autofocus: true %>
3
+ <%= form_for @magic_link do |f| %>
4
+ <div class="field">
5
+ <%= f.label :email %><br />
6
+ <%= f.email_field :email, autofocus: true, autocomplete: "email" %>
7
+ </div>
8
+
5
9
  <%= f.submit "Email me a sign in link", class: "btn btn-primary btn-block" %>
6
10
  <% end %>
7
11
  <br>
@@ -1,3 +1,4 @@
1
1
  Magic::Link::Engine.routes.draw do
2
2
  resources :magic_links, only: [:new, :create]
3
+ get "/magic_links/authenticate", to: "magic_links#authenticate", as: :authenticate
3
4
  end
@@ -1,5 +1,4 @@
1
1
  require "magic/link/engine"
2
- require "magic/link/controller_extensions"
3
2
  require "magic/link/railtie"
4
3
 
5
4
  module Magic
@@ -13,6 +12,9 @@ module Magic
13
12
  mattr_accessor :token_expiration_hours
14
13
  @@token_expiration_hours = 6
15
14
 
15
+ mattr_accessor :after_sign_in_path
16
+ @@after_sign_in_path = "root_path"
17
+
16
18
  class << self
17
19
  def configure
18
20
  yield self
@@ -2,9 +2,7 @@ module Magic
2
2
  module Link
3
3
  class Railtie < ::Rails::Railtie
4
4
  config.to_prepare do
5
- ::ApplicationController.send(:include, Magic::Link::ControllerExtensions)
6
5
  ::ApplicationController.send(:helper, Magic::Link::ApplicationHelper)
7
- ::ApplicationController.send(:before_action, :authenticate_user_from_token!)
8
6
  end
9
7
  end
10
8
  end
@@ -1,5 +1,5 @@
1
1
  module Magic
2
2
  module Link
3
- VERSION = '0.1.0'
3
+ VERSION = '1.2.0'
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: magic-link
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Van Der Beek
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-11-20 00:00:00.000000000 Z
11
+ date: 2020-07-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -16,28 +16,28 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '5.2'
19
+ version: 5.2.2.1
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: '5.2'
26
+ version: 5.2.2.1
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: devise
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: '4'
33
+ version: 4.7.1
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: '4'
40
+ version: 4.7.1
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: sqlite3
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -77,7 +77,6 @@ files:
77
77
  - app/views/magic/link/magic_links/new.html.erb
78
78
  - config/routes.rb
79
79
  - lib/magic/link.rb
80
- - lib/magic/link/controller_extensions.rb
81
80
  - lib/magic/link/engine.rb
82
81
  - lib/magic/link/railtie.rb
83
82
  - lib/magic/link/version.rb
@@ -86,7 +85,7 @@ homepage: https://github.com/dvanderbeek/magic-link
86
85
  licenses:
87
86
  - MIT
88
87
  metadata: {}
89
- post_install_message:
88
+ post_install_message:
90
89
  rdoc_options: []
91
90
  require_paths:
92
91
  - lib
@@ -102,7 +101,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
102
101
  version: '0'
103
102
  requirements: []
104
103
  rubygems_version: 3.0.6
105
- signing_key:
104
+ signing_key:
106
105
  specification_version: 4
107
106
  summary: Devise magic sign in links
108
107
  test_files: []
@@ -1,39 +0,0 @@
1
- module Magic
2
- module Link
3
- module ControllerExtensions
4
- def self.included(base)
5
- base.send(:include, InstanceMethods)
6
- end
7
-
8
- module InstanceMethods
9
- def authenticate_user_from_token!
10
- email = params[:email].presence
11
- token = params[:sign_in_token].presence
12
- user = email && token && Magic::Link.user_class.find_by(email: email)
13
-
14
- if token && send("#{Magic::Link.user_class.name.underscore}_signed_in?")
15
- flash.now[:alert] = "You are already signed in"
16
- elsif user && token_matches?(user) && token_not_expired?(user)
17
- flash[:notice] = "You have signed in successfully"
18
- user.update_columns(sign_in_token: nil, sign_in_token_sent_at: nil)
19
- sign_in user
20
- elsif email && token
21
- flash[:alert] = "Your sign in token is invalid"
22
- redirect_to main_app.root_path
23
- end
24
- end
25
-
26
- def token_matches?(user)
27
- Devise.secure_compare(
28
- user.sign_in_token,
29
- Devise.token_generator.digest(Magic::Link.user_class, :sign_in_token, params[:sign_in_token])
30
- )
31
- end
32
-
33
- def token_not_expired?(user)
34
- user.sign_in_token_sent_at >= Magic::Link.token_expiration_hours.hours.ago
35
- end
36
- end
37
- end
38
- end
39
- end