passwordless 0.5.4 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fa64d2ab5ebc0459f75b9c7156a480228b519f8b5b38f791fc6cba0a780a82cd
4
- data.tar.gz: 4297d10aaa0cbb727a68d3ba79282df3a0345d3fcd6aa041db37a929a345ea0c
3
+ metadata.gz: 00fe76a0b0247e700ff5868fcabf1dc82b1bffddd63437f21d5ec5c4dce83479
4
+ data.tar.gz: ff56c5859f448221da83458c17dd30623bd335942fe77e44bede19144a7dd49e
5
5
  SHA512:
6
- metadata.gz: ad267857c79956191a9b7dc474c2349dfbf1213a39f388339f57dd4d50bf77a69841d3bc4c4bbf227be084b9e138aff9290925bea665436e7548754810fdac4e
7
- data.tar.gz: 11114a1b24a896e5613a496771a193c68b4e170880e422cbd894c284c5e9ee2bf7927ac5beedda95c8c6c1d1946ade7d5b933dddb19754ce2e861cef06573f8a
6
+ metadata.gz: 2e3281f7a60b04f82796a00759a6aea284aeeafb237670c10f458a629ea02b0d55607f155b4efa257209f580aeb394b0bf33c69c5bce250ec3e179e01eecaf89
7
+ data.tar.gz: 81ddaae8d5120e6e1867a8992bc9c0b0f596933ba163dac63a1b3ad39b2b4ba40d84c6b69bb1764283ea9eac39eba199f1fbced0a91f1f93f16f10f01e56bf38
data/README.md CHANGED
@@ -16,8 +16,10 @@ Add authentication to your Rails app without all the icky-ness of passwords.
16
16
  * [Usage](#usage)
17
17
  * [Getting the current user, restricting access, the usual](#getting-the-current-user-restricting-access-the-usual)
18
18
  * [Providing your own templates](#providing-your-own-templates)
19
+ * [Overrides](#overrides)
19
20
  * [Registering new users](#registering-new-users)
20
21
  * [Generating tokens](#generating-tokens)
22
+ * [Token and Session Expiry](#token-and-session-expiry)
21
23
  * [Redirecting back after sign-in](#redirecting-back-after-sign-in)
22
24
  * [URLs and links](#urls-and-links)
23
25
  * [E-mail security](#e-mail-security)
@@ -51,7 +53,7 @@ Then specify which field on your `User` record is the email field with:
51
53
  ```ruby
52
54
  class User < ApplicationRecord
53
55
  validates :email, presence: true, uniqueness: { case_sensitive: false }
54
-
56
+
55
57
  passwordless_with :email # <-- here!
56
58
  end
57
59
  ```
@@ -73,13 +75,13 @@ Passwordless doesn't give you `current_user` automatically -- it's dead easy to
73
75
  ```ruby
74
76
  class ApplicationController < ActionController::Base
75
77
  include Passwordless::ControllerHelpers # <-- This!
76
-
78
+
77
79
  # ...
78
-
80
+
79
81
  helper_method :current_user
80
-
82
+
81
83
  private
82
-
84
+
83
85
  def current_user
84
86
  @current_user ||= authenticate_by_cookie(User)
85
87
  end
@@ -96,7 +98,7 @@ Et voilà:
96
98
  ```ruby
97
99
  class VerySecretThingsController < ApplicationController
98
100
  before_action :require_user!
99
-
101
+
100
102
  def index
101
103
  @things = current_user.very_secret_things
102
104
  end
@@ -118,6 +120,22 @@ app/views/passwordless/mailer/magic_link.text.erb
118
120
 
119
121
  See [the bundled views](https://github.com/mikker/passwordless/tree/master/app/views/passwordless).
120
122
 
123
+ ### Overrides
124
+
125
+ By default `passwordless` uses the `passwordless_with` column you specify in the model to case insensitively fetch the resource during authentication. You can override this and provide your own customer fetcher by defining a class method `fetch_resource_for_passwordless` in your passwordless model. The method will be supplied with the downcased email and should return an `ActiveRecord` instance of the model.
126
+
127
+ Example time:
128
+
129
+ Let's say we would like to fetch the record and if it doesn't exist, create automatically.
130
+
131
+ ```ruby
132
+ class User < ApplicationRecord
133
+ def self.fetch_resource_for_passwordless(email)
134
+ find_or_create_by(email: email)
135
+ end
136
+ end
137
+ ```
138
+
121
139
  ### Registering new users
122
140
 
123
141
  Because your `User` record is like any other record, you create one like you normally would. Passwordless provides a helper method you can use to sign in the created user after it is saved like so:
@@ -129,7 +147,7 @@ class UsersController < ApplicationController
129
147
 
130
148
  def create
131
149
  @user = User.new user_params
132
-
150
+
133
151
  if @user.save
134
152
  sign_in @user # <-- And this!
135
153
  redirect_to @user, flash: {notice: 'Welcome!'}
@@ -137,7 +155,7 @@ class UsersController < ApplicationController
137
155
  render :new
138
156
  end
139
157
  end
140
-
158
+
141
159
  # ...
142
160
  end
143
161
  ```
@@ -154,6 +172,32 @@ Passwordless.token_generator = -> (session) {
154
172
 
155
173
  Session is going to keep generating tokens until it finds one that hasn't been used yet. So be sure to use some kind of method where matches are unlikely.
156
174
 
175
+ ### Token and Session Expiry
176
+
177
+ Token timeout is the time by which the sign in token is invalidated. Post the timeout, the token cannot be used to sign-in to the app and the user would need to request it again.
178
+
179
+ Session expiry is the expiration time of the session of a logged in user. Once this is expired, user would need to log back in to create a new session.
180
+
181
+ #### Token timeout
182
+
183
+ By default, sign in tokens generated by Passwordless are made invalid after `1.hour` from the time they are generated. If you wish you can override this and supply your custom Proc function that will return a valid datetime object. Make sure the generated time is in the future.
184
+
185
+ > Make sure to use a `.call`able object, like a proc or lambda as it will be called everytime a session is created.
186
+
187
+ ```ruby
188
+ Passwordless.timeout_at = lambda { 2.hours.from_now }
189
+ ```
190
+
191
+ #### Session Expiry
192
+
193
+ Session expiry is the time when the actual session is itself expired, i.e. users will be logged out and has to sign back in post this expiry time. By default, sessions are valid for `1.year` from the time they are generated. You can override by providing your custom Proc function that returns a datetime object.
194
+
195
+ > Make sure to use a `.call`able object, like a proc or lambda as it will be called everytime a session is created.
196
+
197
+ ```ruby
198
+ Passwordless.expires_at = lambda { 24.hours.from_now }
199
+ ```
200
+
157
201
  ### Redirecting back after sign-in
158
202
 
159
203
  By default Passwordless will redirect back to where the user wanted to go **if** it knows where that is, so you'll have to help it. `Passwordless::ControllerHelpers` provide a method for this:
@@ -161,9 +205,9 @@ By default Passwordless will redirect back to where the user wanted to go **if**
161
205
  ```ruby
162
206
  class ApplicationController < ActionController::Base
163
207
  include Passwordless::ControllerHelpers # <-- Probably already have this!
164
-
208
+
165
209
  # ...
166
-
210
+
167
211
  def require_user!
168
212
  return if current_user
169
213
  save_passwordless_redirect_location!(User) # <-- here we go!
@@ -181,7 +225,7 @@ By default, Passwordless uses the resource name given to `passwordless_for` to g
181
225
  ```ruby
182
226
  passwordless_for :users
183
227
  # <%= users.sign_in_path %> # => /users/sign_in
184
-
228
+
185
229
  passwordless_for :users, at: '/', as: :auth
186
230
  # <%= auth.sign_in_path %> # => /sign_in
187
231
  ```
@@ -90,9 +90,15 @@ module Passwordless
90
90
  end
91
91
 
92
92
  def find_authenticatable
93
- authenticatable_class.where(
94
- "lower(#{email_field}) = ?", params[:passwordless][email_field].downcase
95
- ).first
93
+ email = params[:passwordless][email_field].downcase
94
+
95
+ if authenticatable_class.respond_to?(:fetch_resource_for_passwordless)
96
+ authenticatable_class.fetch_resource_for_passwordless(email)
97
+ else
98
+ authenticatable_class.where(
99
+ "lower(#{email_field}) = ?", params[:passwordless][email_field].downcase
100
+ ).first
101
+ end
96
102
  end
97
103
 
98
104
  def find_session
@@ -8,6 +8,7 @@ module Passwordless
8
8
  polymorphic: true, inverse_of: :passwordless_sessions
9
9
 
10
10
  validates \
11
+ :authenticatable,
11
12
  :timeout_at,
12
13
  :expires_at,
13
14
  :user_agent,
@@ -28,8 +29,8 @@ module Passwordless
28
29
  private
29
30
 
30
31
  def set_defaults
31
- self.expires_at ||= 1.year.from_now
32
- self.timeout_at ||= 1.hour.from_now
32
+ self.expires_at ||= Passwordless.expires_at.call
33
+ self.timeout_at ||= Passwordless.timeout_at.call
33
34
  self.token ||= loop do
34
35
  token = Passwordless.token_generator.call(self)
35
36
  break token unless Session.find_by(token: token)
@@ -9,4 +9,7 @@ module Passwordless
9
9
  mattr_accessor(:token_generator) { UrlSafeBase64Generator.new }
10
10
  mattr_accessor(:redirect_back_after_sign_in) { true }
11
11
  mattr_accessor(:mounted_as) { :configured_when_mounting_passwordless }
12
+
13
+ mattr_accessor(:expires_at) { lambda { 1.year.from_now } }
14
+ mattr_accessor(:timeout_at) { lambda { 1.hour.from_now } }
12
15
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Passwordless
4
- VERSION = '0.5.4' # :nodoc:
4
+ VERSION = '0.6.0' # :nodoc:
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: passwordless
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.4
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mikkel Malmberg
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-06-22 00:00:00.000000000 Z
11
+ date: 2019-01-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -127,8 +127,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
127
127
  - !ruby/object:Gem::Version
128
128
  version: '0'
129
129
  requirements: []
130
- rubyforge_project:
131
- rubygems_version: 2.7.6
130
+ rubygems_version: 3.0.2
132
131
  signing_key:
133
132
  specification_version: 4
134
133
  summary: Add authentication to your app without all the ickyness of passwords.