passwordless 0.11.0 → 1.0.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +112 -189
- data/Rakefile +7 -7
- data/app/controllers/passwordless/sessions_controller.rb +121 -39
- data/app/mailers/passwordless/mailer.rb +13 -11
- data/app/models/passwordless/session.rb +25 -12
- data/app/views/passwordless/mailer/sign_in.text.erb +1 -0
- data/app/views/passwordless/sessions/new.html.erb +8 -4
- data/app/views/passwordless/sessions/show.html.erb +5 -0
- data/config/locales/en.yml +18 -6
- data/config/routes.rb +0 -4
- data/db/migrate/20171104221735_create_passwordless_sessions.rb +1 -3
- data/lib/generators/passwordless/views_generator.rb +5 -5
- data/lib/passwordless/config.rb +71 -0
- data/lib/passwordless/controller_helpers.rb +31 -69
- data/lib/passwordless/engine.rb +2 -6
- data/lib/passwordless/errors.rb +4 -0
- data/lib/passwordless/router_helpers.rb +24 -10
- data/lib/passwordless/short_token_generator.rb +9 -0
- data/lib/passwordless/test_helpers.rb +19 -9
- data/lib/passwordless/token_digest.rb +18 -0
- data/lib/passwordless/version.rb +1 -1
- data/lib/passwordless.rb +5 -18
- metadata +12 -52
- data/app/views/passwordless/mailer/magic_link.text.erb +0 -1
- data/app/views/passwordless/sessions/create.html.erb +0 -1
- data/lib/passwordless/url_safe_base_64_generator.rb +0 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '09a1ddce2bcfe831bf08b8e0e2e48ce7d8941ea4a44ed9ea0091de3ece68b9f3'
|
4
|
+
data.tar.gz: 35d3d30954025caa77b06a2ff6c51579cbe78135579733cdb92323cd1c140e7f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 16be37d7458a6749f1df567fa15b7e480913a21a85ec3fab9dfabc737e4ab85308a93f387c663939b863967968e9e26c9e3bdfb1ec1b26e957570a109bd170ea
|
7
|
+
data.tar.gz: 5715a453783257aa2f3065f85e9a2b3a71079fca9519ff7fbc92e0b5dfe491b5b8846f7dfd24e458b15589746be0c5fd6d5996ec7c3feebc2ed9bf6c3aa1836a
|
data/README.md
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
**NOTE:** Passwordless is currently going through some breaking changes. Be aware that the docs in `master` aren't necessarily the same as for you installed version.
|
2
|
+
|
3
|
+
---
|
4
|
+
|
1
5
|
<p align='center'>
|
2
6
|
<img src='https://s3.brnbw.com/Passwordless-title-gaIVkX0sPg.svg' alt='Passwordless' />
|
3
7
|
<br />
|
@@ -12,37 +16,34 @@ Add authentication to your Rails app without all the icky-ness of passwords.
|
|
12
16
|
|
13
17
|
## Table of Contents
|
14
18
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
19
|
+
<!--toc:start-->
|
20
|
+
|
21
|
+
- [Table of Contents](#table-of-contents)
|
22
|
+
- [Installation](#installation)
|
23
|
+
- [Usage](#usage)
|
24
|
+
- [Getting the current user, restricting access, the usual](#getting-the-current-user-restricting-access-the-usual)
|
25
|
+
- [Providing your own templates](#providing-your-own-templates)
|
26
|
+
- [Registering new users](#registering-new-users)
|
27
|
+
- [URLs and links](#urls-and-links)
|
28
|
+
- [Configuration](#configuration)
|
29
|
+
- [Delivery method](#delivery-method)
|
30
|
+
- [Token generation](#token-generation)
|
31
|
+
- [Timeout and Expiry](#timeout-and-expiry)
|
32
|
+
- [Redirection after sign-in](#redirection-after-sign-in)
|
33
|
+
- [Looking up the user](#looking-up-the-user)
|
34
|
+
- [Claiming tokens](#claiming-tokens)
|
35
|
+
- [Test helpers](#test-helpers)
|
36
|
+
- [Security considerations](#security-considerations)
|
37
|
+
- [Alternatives](#alternatives)
|
38
|
+
- [License](#license)
|
39
|
+
<!--toc:end-->
|
33
40
|
|
34
41
|
## Installation
|
35
42
|
|
36
|
-
Add
|
37
|
-
|
38
|
-
```ruby
|
39
|
-
gem 'passwordless'
|
40
|
-
```
|
41
|
-
|
42
|
-
Install it and copy over the migrations:
|
43
|
+
Add to your bundle and copy over the migrations:
|
43
44
|
|
44
45
|
```sh
|
45
|
-
$ bundle
|
46
|
+
$ bundle add passwordless
|
46
47
|
$ bin/rails passwordless:install:migrations
|
47
48
|
```
|
48
49
|
|
@@ -58,7 +59,10 @@ Then specify which field on your `User` record is the email field with:
|
|
58
59
|
|
59
60
|
```ruby
|
60
61
|
class User < ApplicationRecord
|
61
|
-
validates :email,
|
62
|
+
validates :email,
|
63
|
+
presence: true,
|
64
|
+
uniqueness: { case_sensitive: false },
|
65
|
+
format: { with: URI::MailTo::EMAIL_REGEXP }
|
62
66
|
|
63
67
|
passwordless_with :email # <-- here!
|
64
68
|
end
|
@@ -94,6 +98,7 @@ class ApplicationController < ActionController::Base
|
|
94
98
|
|
95
99
|
def require_user!
|
96
100
|
return if current_user
|
101
|
+
save_passwordless_redirect_location!(User) # <-- optional, see below
|
97
102
|
redirect_to root_path, flash: { error: 'You are not worthy!' }
|
98
103
|
end
|
99
104
|
end
|
@@ -113,30 +118,19 @@ end
|
|
113
118
|
|
114
119
|
### Providing your own templates
|
115
120
|
|
116
|
-
|
121
|
+
To make Passwordless look like your app, override the bundled views by adding your own. You can manually copy the specific views that you need or copy them to your application with `rails generate passwordless:views`.
|
117
122
|
|
118
|
-
|
123
|
+
Passwordless has 2 action views and 1 mailer view:
|
119
124
|
|
120
125
|
```sh
|
121
126
|
# the form where the user inputs their email address
|
122
127
|
app/views/passwordless/sessions/new.html.erb
|
123
|
-
#
|
124
|
-
app/views/passwordless/sessions/
|
125
|
-
# the
|
126
|
-
app/views/passwordless/mailer/
|
127
|
-
```
|
128
|
-
|
129
|
-
If you'd like to let the user know whether or not a record was found, `@resource` is provided to the view. You may override `app/views/passwordless/session/create.html.erb` for example like so:
|
130
|
-
```erb
|
131
|
-
<% if @resource.present? %>
|
132
|
-
<p>User found, check your inbox</p>
|
133
|
-
<% else %>
|
134
|
-
<p>No user found with the provided email address</p>
|
135
|
-
<% end %>
|
128
|
+
# the form where the user inputs their just received token
|
129
|
+
app/views/passwordless/sessions/show.html.erb
|
130
|
+
# the email with the token and magic link
|
131
|
+
app/views/passwordless/mailer/sign_in.text.erb
|
136
132
|
```
|
137
133
|
|
138
|
-
Please note that, from a security standpoint, this is a **bad practice** because you'd be giving information about which users are registered on your system. It is recommended to use a single message similar to the default one: "If we found you in the system, we've sent you an email". The **best practice** is to never expose which emails are registered on your system.
|
139
|
-
|
140
134
|
See [the bundled views](https://github.com/mikker/passwordless/tree/master/app/views/passwordless).
|
141
135
|
|
142
136
|
### Registering new users
|
@@ -149,13 +143,13 @@ class UsersController < ApplicationController
|
|
149
143
|
# (unless you already have it in your ApplicationController)
|
150
144
|
|
151
145
|
def create
|
152
|
-
@user = User.new
|
146
|
+
@user = User.new(user_params)
|
153
147
|
|
154
148
|
if @user.save
|
155
|
-
sign_in
|
156
|
-
redirect_to
|
149
|
+
sign_in(build_passwordless_session(@user)) # <-- This!
|
150
|
+
redirect_to(@user, flash: { notice: 'Welcome!' })
|
157
151
|
else
|
158
|
-
render
|
152
|
+
render(:new)
|
159
153
|
end
|
160
154
|
end
|
161
155
|
|
@@ -169,134 +163,90 @@ By default, Passwordless uses the resource name given to `passwordless_for` to g
|
|
169
163
|
|
170
164
|
```ruby
|
171
165
|
passwordless_for :users
|
172
|
-
# <%=
|
166
|
+
# <%= users_sign_in_path %> # => /users/sign_in
|
173
167
|
|
174
168
|
passwordless_for :users, at: '/', as: :auth
|
175
|
-
# <%=
|
169
|
+
# <%= auth_sign_in_path %> # => /sign_in
|
176
170
|
```
|
177
171
|
|
178
|
-
Also be sure to
|
172
|
+
Also be sure to
|
173
|
+
[specify ActionMailer's `default_url_options.host`](http://guides.rubyonrails.org/action_mailer_basics.html#generating-urls-in-action-mailer-views).
|
179
174
|
|
180
|
-
|
175
|
+
## Configuration
|
181
176
|
|
182
|
-
|
177
|
+
To customize Passwordless, create a file `config/initializers/passwordless.rb`.
|
183
178
|
|
184
|
-
|
179
|
+
The default values are shown below. It's recommended to only include the ones that you specifically want to modify.
|
185
180
|
|
186
181
|
```ruby
|
187
|
-
Passwordless.
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
182
|
+
Passwordless.configure do |config|
|
183
|
+
config.default_from_address = "CHANGE_ME@example.com"
|
184
|
+
config.parent_mailer = "ActionMailer::Base"
|
185
|
+
config.restrict_token_reuse = false # Can a token/link be used multiple times?
|
186
|
+
config.token_generator = Passwordless::ShortTokenGenerator.new # Used to generate magic link tokens.
|
187
|
+
|
188
|
+
config.expires_at = lambda { 1.year.from_now } # How long until a signed in session expires.
|
189
|
+
config.timeout_at = lambda { 10.minutes.from_now } # How long until a token/magic link times out.
|
190
|
+
|
191
|
+
config.redirect_back_after_sign_in = true # When enabled the user will be redirected to their previous page, or a page specified by the `destination_path` query parameter, if available.
|
192
|
+
config.redirect_to_response_options = {} # Additional options for redirects.
|
193
|
+
config.success_redirect_path = '/' # After a user successfully signs in
|
194
|
+
config.failure_redirect_path = '/' # After a sign in fails
|
195
|
+
config.sign_out_redirect_path = '/' # After a user signs out
|
193
196
|
end
|
194
197
|
```
|
195
198
|
|
196
|
-
|
199
|
+
### Delivery method
|
197
200
|
|
198
|
-
|
201
|
+
By default, Passwordless sends emails. See [Providing your own templates](#providing-your-own-templates). If you need to customize this further, you can do so in the `after_session_save` callback.
|
199
202
|
|
200
|
-
|
201
|
-
|
202
|
-
However, you can accomplish this with the following snippet of code.
|
203
|
+
In `config/initializers/passwordless.rb`:
|
203
204
|
|
204
205
|
```ruby
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
})
|
210
|
-
session.save!
|
211
|
-
@magic_link = send(Passwordless.mounted_as).token_sign_in_url(session.token)
|
212
|
-
```
|
206
|
+
Passwordless.configure do |config|
|
207
|
+
config.after_session_save = lambda do |session, request|
|
208
|
+
# Default behavior is
|
209
|
+
# Passwordless::Mailer.sign_in(session).deliver_now
|
213
210
|
|
214
|
-
You can
|
215
|
-
|
216
|
-
@magic_link = "#{@magic_link}?destination_path=/your-custom-path"
|
217
|
-
```
|
218
|
-
|
219
|
-
### Overrides
|
220
|
-
|
221
|
-
By default `passwordless` uses the `passwordless_with` column to _case insensitively_ fetch the resource.
|
222
|
-
|
223
|
-
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 called with the downcased email and should return an `ActiveRecord` instance of the model.
|
224
|
-
|
225
|
-
Example time:
|
226
|
-
|
227
|
-
Let's say we would like to fetch the record and if it doesn't exist, create automatically.
|
228
|
-
|
229
|
-
```ruby
|
230
|
-
class User < ApplicationRecord
|
231
|
-
def self.fetch_resource_for_passwordless(email)
|
232
|
-
find_or_create_by(email: email)
|
211
|
+
# You can change behavior to do something with session model. For example,
|
212
|
+
# SmsApi.send_sms(session.authenticatable.phone_number, session.token)
|
233
213
|
end
|
234
214
|
end
|
235
215
|
```
|
236
216
|
|
237
|
-
|
238
|
-
|
239
|
-
The following configuration parameters are supported. You can override these for example in `initializers/passwordless.rb`.
|
217
|
+
### Token generation
|
240
218
|
|
241
|
-
|
219
|
+
By default Passwordless generates short, 6-digit, alpha numeric tokens. You can change the generator using `Passwordless.config.token_generator` to something else that responds to `call(session)` eg.:
|
242
220
|
|
243
221
|
```ruby
|
244
|
-
Passwordless.
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
Passwordless.expires_at = lambda { 1.year.from_now } # How long until a passwordless session expires.
|
251
|
-
Passwordless.timeout_at = lambda { 1.hour.from_now } # How long until a magic link expires.
|
252
|
-
|
253
|
-
# Default redirection paths
|
254
|
-
Passwordless.success_redirect_path = '/' # When a user succeeds in logging in.
|
255
|
-
Passwordless.failure_redirect_path = '/' # When a a login is failed for any reason.
|
256
|
-
Passwordless.sign_out_redirect_path = '/' # When a user logs out.
|
257
|
-
```
|
258
|
-
|
259
|
-
### Customizing token generation
|
260
|
-
|
261
|
-
By default Passwordless generates tokens using `SecureRandom.urlsafe_base64` but you can change that by setting `Passwordless.token_generator` to something else that responds to `call(session)` eg.:
|
262
|
-
|
263
|
-
```ruby
|
264
|
-
Passwordless.token_generator = -> (session) {
|
265
|
-
"probably-stupid-token-#{session.user_agent}-#{Time.current}"
|
266
|
-
}
|
222
|
+
Passwordless.configure do |config|
|
223
|
+
config.token_generator = lambda do |session|
|
224
|
+
"probably-stupid-token-#{session.user_agent}-#{Time.current}"
|
225
|
+
end
|
226
|
+
end
|
267
227
|
```
|
268
228
|
|
269
|
-
|
229
|
+
Passwordless will 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.
|
270
230
|
|
271
|
-
###
|
231
|
+
### Timeout and Expiry
|
272
232
|
|
273
|
-
|
233
|
+
The _timeout_ is the time by which the generated token and magic link is invalidated. After this the token cannot be used to sign in to your app and the user will need to request a new token.
|
274
234
|
|
275
|
-
|
235
|
+
The _expiry_ is the expiration time of the session of a logged in user. Once this is expired, the user is signed out.
|
276
236
|
|
277
|
-
|
237
|
+
**Note:** Passwordless' session relies on Rails' own session and so will never live longer than that.
|
278
238
|
|
279
|
-
|
280
|
-
|
281
|
-
> Make sure to use a `.call`able object, like a proc or lambda as it will be called everytime a session is created.
|
239
|
+
To configure your Rails session, in `config/initializers/session_store.rb`:
|
282
240
|
|
283
241
|
```ruby
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
#### Session Expiry
|
288
|
-
|
289
|
-
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.
|
290
|
-
|
291
|
-
> Make sure to use a `.call`able object, like a proc or lambda as it will be called everytime a session is created.
|
292
|
-
|
293
|
-
```ruby
|
294
|
-
Passwordless.expires_at = lambda { 24.hours.from_now }
|
242
|
+
Rails.application.config.session_store :cookie_store,
|
243
|
+
expire_after: 1.year,
|
244
|
+
# ...
|
295
245
|
```
|
296
246
|
|
297
|
-
###
|
247
|
+
### Redirection after sign-in
|
298
248
|
|
299
|
-
By default Passwordless will redirect back to where the user wanted to go
|
249
|
+
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:
|
300
250
|
|
301
251
|
```ruby
|
302
252
|
class ApplicationController < ActionController::Base
|
@@ -306,71 +256,45 @@ class ApplicationController < ActionController::Base
|
|
306
256
|
|
307
257
|
def require_user!
|
308
258
|
return if current_user
|
309
|
-
save_passwordless_redirect_location!(User) # <--
|
259
|
+
save_passwordless_redirect_location!(User) # <-- this one!
|
310
260
|
redirect_to root_path, flash: {error: 'You are not worthy!'}
|
311
261
|
end
|
312
262
|
end
|
313
263
|
```
|
314
264
|
|
315
|
-
This can be turned off with `Passwordless.redirect_back_after_sign_in = false
|
316
|
-
|
317
|
-
### Claiming tokens
|
318
|
-
|
319
|
-
Opt-in for marking tokens as `claimed` so they can only be used once.
|
320
|
-
|
321
|
-
config/initializers/passwordless.rb
|
322
|
-
|
323
|
-
```ruby
|
324
|
-
# Default is `false`
|
325
|
-
Passwordless.restrict_token_reuse = true
|
326
|
-
```
|
327
|
-
|
328
|
-
#### Upgrading an existing Rails app to use claim token
|
265
|
+
This can also be turned off with `Passwordless.config.redirect_back_after_sign_in = false`.
|
329
266
|
|
330
|
-
|
267
|
+
### Looking up the user
|
331
268
|
|
332
|
-
|
333
|
-
<summary>Example migration</summary>
|
269
|
+
By default Passwordless uses the `passwordless_with` column to _case insensitively_ fetch the user resource.
|
334
270
|
|
335
|
-
|
336
|
-
bin/rails generate migration add_claimed_at_to_passwordless_sessions
|
337
|
-
```
|
271
|
+
You can override this by defining a class method `fetch_resource_for_passwordless` in your user model. This method will be called with the down-cased, stripped `email` and should return an `ActiveRecord` instance.
|
338
272
|
|
339
273
|
```ruby
|
340
|
-
class
|
341
|
-
def
|
342
|
-
|
274
|
+
class User < ApplicationRecord
|
275
|
+
def self.fetch_resource_for_passwordless(email)
|
276
|
+
find_or_create_by(email: email)
|
343
277
|
end
|
344
278
|
end
|
345
|
-
|
346
279
|
```
|
347
|
-
</details>
|
348
280
|
|
349
|
-
###
|
281
|
+
### Claiming tokens
|
282
|
+
|
283
|
+
By default, a token/magic link **can** be used more than once.
|
350
284
|
|
351
|
-
|
352
|
-
to change the type of `passwordless`' `authenticatable_id` field to match your primary key type (this will also involve dropping and recreating associated indices).
|
285
|
+
To change, in `config/initializers/passwordless.rb`:
|
353
286
|
|
354
|
-
Here is an example migration you can use:
|
355
287
|
```ruby
|
356
|
-
|
357
|
-
|
358
|
-
remove_index :passwordless_sessions, column: [:authenticatable_type, :authenticatable_id] if index_exists? :authenticatable_type, :authenticatable_id
|
359
|
-
remove_column :passwordless_sessions, :authenticatable_id
|
360
|
-
add_column :passwordless_sessions, :authenticatable_id, :uuid
|
361
|
-
add_index :passwordless_sessions, [:authenticatable_type, :authenticatable_id], name: 'authenticatable'
|
362
|
-
end
|
288
|
+
Passwordless.configure do |config|
|
289
|
+
config.restrict_token_reuse = true
|
363
290
|
end
|
364
291
|
```
|
365
292
|
|
366
|
-
|
367
|
-
|
368
|
-
## Testing helpers
|
293
|
+
## Test helpers
|
369
294
|
|
370
295
|
To help with testing, a set of test helpers are provided.
|
371
296
|
|
372
|
-
If you are using RSpec, add the following line to your `spec/rails_helper.rb
|
373
|
-
`spec/spec_helper.rb` if `rails_helper.rb` does not exist:
|
297
|
+
If you are using RSpec, add the following line to your `spec/rails_helper.rb`:
|
374
298
|
|
375
299
|
```ruby
|
376
300
|
require "passwordless/test_helpers"
|
@@ -382,7 +306,6 @@ If you are using TestUnit, add this line to your `test/test_helper.rb`:
|
|
382
306
|
require "passwordless/test_helpers"
|
383
307
|
```
|
384
308
|
|
385
|
-
|
386
309
|
Then in your controller, request, and system tests/specs, you can utilize the following methods:
|
387
310
|
|
388
311
|
```ruby
|
@@ -390,18 +313,18 @@ passwordless_sign_in(user) # signs you in as a user
|
|
390
313
|
passwordless_sign_out # signs out user
|
391
314
|
```
|
392
315
|
|
393
|
-
##
|
316
|
+
## Security considerations
|
394
317
|
|
395
|
-
There's no reason that this approach should be less secure than the usual username/password combo. In fact this is most often a more secure option, as users don't get to choose the
|
318
|
+
There's no reason that this approach should be less secure than the usual username/password combo. In fact this is most often a more secure option, as users don't get to choose the horrible passwords they can't seem to stop using. In a way, this is just the same as having each user go through "Forgot password" on every login.
|
396
319
|
|
397
|
-
But be aware that when everyone authenticates via emails
|
320
|
+
But be aware that when everyone authenticates via emails, the way you send those mails becomes a weak spot. Email services usually provide a log of all the mails you send so if your email delivery provider account is compromised, every user in the system is as well. (This is the same for "Forgot password".) [Reddit was once compromised](https://thenextweb.com/hardfork/2018/01/05/reddit-bitcoin-cash-stolen-hack/) using this method.
|
398
321
|
|
399
|
-
Ideally you should set up your email provider to not log these mails. And be sure to turn on 2-factor
|
322
|
+
Ideally you should set up your email provider to not log these mails. And be sure to turn on non-SMS 2-factor authentication if your provider supports it.
|
400
323
|
|
401
|
-
|
324
|
+
## Alternatives
|
402
325
|
|
403
326
|
- [OTP JWT](https://github.com/stas/otp-jwt) -- Passwordless JSON Web Tokens
|
404
327
|
|
405
|
-
|
328
|
+
## License
|
406
329
|
|
407
330
|
MIT
|
data/Rakefile
CHANGED
@@ -2,17 +2,19 @@
|
|
2
2
|
|
3
3
|
begin
|
4
4
|
require "bundler/setup"
|
5
|
+
|
5
6
|
rescue LoadError
|
6
|
-
puts
|
7
|
+
puts("You must `gem install bundler` and `bundle install` to run rake tasks")
|
7
8
|
end
|
8
9
|
|
9
10
|
require "yard"
|
11
|
+
|
10
12
|
YARD::Rake::YardocTask.new
|
11
|
-
task
|
13
|
+
task(docs: :yard)
|
12
14
|
|
13
15
|
APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
|
14
|
-
load
|
15
|
-
load
|
16
|
+
load("rails/tasks/engine.rake")
|
17
|
+
load("rails/tasks/statistics.rake")
|
16
18
|
|
17
19
|
require "bundler/gem_tasks"
|
18
20
|
|
@@ -24,6 +26,4 @@ Rake::TestTask.new(:test) do |t|
|
|
24
26
|
t.verbose = false
|
25
27
|
end
|
26
28
|
|
27
|
-
task
|
28
|
-
|
29
|
-
require "standard/rake"
|
29
|
+
task(default: :test)
|