avocado 0.5.0 → 0.7.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 +4 -4
- data/CHANGELOG.md +59 -14
- data/README.md +8 -43
- data/Rakefile +0 -2
- data/app/controllers/avocado/affirmations_controller.rb +21 -18
- data/app/controllers/avocado/base_controller.rb +26 -5
- data/app/controllers/avocado/credentials_controller.rb +41 -0
- data/app/controllers/avocado/emails_controller.rb +9 -17
- data/app/controllers/avocado/events_controller.rb +3 -3
- data/app/controllers/avocado/passwords_controller.rb +8 -8
- data/app/controllers/avocado/recoveries_controller.rb +8 -41
- data/app/controllers/avocado/registrations_controller.rb +7 -14
- data/app/controllers/avocado/sessions_controller.rb +21 -13
- data/app/controllers/avocado/verifications_controller.rb +14 -15
- data/app/views/avocado/affirmations/_form.html.erb +4 -0
- data/app/views/avocado/affirmations/edit.html.erb +7 -0
- data/app/views/avocado/affirmations/new.html.erb +2 -4
- data/app/views/avocado/{recoveries/edit.html.erb → credentials/_form.html.erb} +4 -13
- data/app/views/avocado/credentials/edit.html.erb +12 -0
- data/app/views/avocado/emails/_form.html.erb +8 -0
- data/app/views/avocado/emails/edit.html.erb +1 -6
- data/app/views/avocado/mailer/email_affirmation.text.erb +1 -1
- data/app/views/avocado/mailer/email_verification.text.erb +1 -1
- data/app/views/avocado/mailer/password_reset.text.erb +1 -1
- data/app/views/avocado/passwords/_form.html.erb +12 -0
- data/app/views/avocado/passwords/edit.html.erb +1 -9
- data/app/views/avocado/recoveries/_form.html.erb +4 -0
- data/app/views/avocado/recoveries/new.html.erb +2 -4
- data/app/views/avocado/registrations/_form.html.erb +12 -0
- data/app/views/avocado/registrations/new.html.erb +1 -12
- data/app/views/avocado/sessions/_form.html.erb +8 -0
- data/app/views/avocado/sessions/new.html.erb +1 -4
- data/app/views/avocado/verifications/edit.html.erb +7 -0
- data/config/locales/en.yml +45 -0
- data/config/routes/avocado.rb +11 -0
- data/config.ru +0 -2
- data/docs/USAGE.md +164 -0
- data/lib/avocado/authentication.rb +2 -4
- data/lib/avocado/current.rb +0 -2
- data/lib/avocado/engine.rb +5 -2
- data/lib/avocado/event.rb +0 -2
- data/lib/avocado/mailer.rb +0 -2
- data/lib/avocado/session.rb +6 -2
- data/lib/avocado/session_callbacks.rb +0 -2
- data/lib/avocado/user.rb +0 -2
- data/lib/avocado/user_callbacks.rb +0 -2
- data/lib/avocado/user_tokens.rb +0 -2
- data/lib/avocado/user_validations.rb +0 -2
- data/lib/avocado/version.rb +1 -3
- data/lib/avocado.rb +1 -2
- data/lib/generators/avocado/migrations/migrations_generator.rb +34 -0
- data/lib/generators/avocado/migrations/templates/create_events.rb.tt +12 -0
- data/lib/generators/avocado/migrations/templates/create_sessions.rb.tt +12 -0
- data/lib/generators/avocado/migrations/templates/create_users.rb.tt +11 -0
- data/lib/generators/avocado/views/views_generator.rb +21 -0
- metadata +27 -38
- data/config/routes.rb +0 -12
@@ -1,20 +1,23 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
1
|
module Avocado
|
4
2
|
class VerificationsController < BaseController
|
5
|
-
with_options only:
|
3
|
+
with_options only: %i[edit update] do
|
6
4
|
skip_before_action :authenticate
|
7
5
|
before_action :set_user
|
8
6
|
end
|
9
7
|
|
10
|
-
def
|
8
|
+
def edit
|
9
|
+
end
|
10
|
+
|
11
|
+
def update
|
11
12
|
@user.update! verified: true
|
12
|
-
redirect_to root_path,
|
13
|
+
redirect_to root_path,
|
14
|
+
notice: t(".success")
|
13
15
|
end
|
14
16
|
|
15
17
|
def create
|
16
|
-
send_email_verification
|
17
|
-
redirect_to root_path,
|
18
|
+
send_email_verification(current_user)
|
19
|
+
redirect_to root_path,
|
20
|
+
notice: t(".success")
|
18
21
|
end
|
19
22
|
|
20
23
|
private
|
@@ -22,17 +25,13 @@ module Avocado
|
|
22
25
|
def set_user
|
23
26
|
@user = user_from_signed_email_verification_token
|
24
27
|
rescue ActiveSupport::MessageVerifier::InvalidSignature
|
25
|
-
redirect_to root_path,
|
28
|
+
redirect_to root_path,
|
29
|
+
alert: t(".errors.invalid_token")
|
26
30
|
end
|
27
31
|
|
28
32
|
def user_from_signed_email_verification_token
|
29
|
-
::User
|
30
|
-
|
31
|
-
|
32
|
-
def send_email_verification
|
33
|
-
mailer_for(current_user)
|
34
|
-
.email_verification
|
35
|
-
.deliver_later
|
33
|
+
::User
|
34
|
+
.find_by_token_for!(:email_verification, params[:id])
|
36
35
|
end
|
37
36
|
end
|
38
37
|
end
|
@@ -6,9 +6,7 @@
|
|
6
6
|
<%= link_to "Reset your password", new_recovery_path %>
|
7
7
|
</p>
|
8
8
|
|
9
|
-
<%= form_with url: affirmations_path do |form| %>
|
10
|
-
<%= form
|
11
|
-
<%= form.email_field :email, autofocus: true, autocomplete: "email", required: true %>
|
12
|
-
|
9
|
+
<%= form_with url: affirmations_path, scope: :user do |form| %>
|
10
|
+
<%= render form %>
|
13
11
|
<%= form.button "Submit", name: nil %>
|
14
12
|
<% end -%>
|
@@ -1,17 +1,8 @@
|
|
1
|
-
<
|
2
|
-
Change your password
|
3
|
-
</h2>
|
4
|
-
|
5
|
-
<p>
|
6
|
-
<%= link_to "Sign in to your account" %>
|
7
|
-
</p>
|
8
|
-
|
9
|
-
<%= form_with model: @user, url: recovery_path(id: params[:id]), method: :patch do |form| %>
|
1
|
+
<div>
|
10
2
|
<%= form.label :password %>
|
11
3
|
<%= form.password_field :password, autocomplete: "new-password", required: true %>
|
12
|
-
|
4
|
+
</div>
|
5
|
+
<div>
|
13
6
|
<%= form.label :password_confirmation %>
|
14
7
|
<%= form.password_field :password_confirmation, autocomplete: "new-password", required: true %>
|
15
|
-
|
16
|
-
<%= form.button "Submit", name: nil %>
|
17
|
-
<% end %>
|
8
|
+
</div>
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<h2>
|
2
|
+
Change your password
|
3
|
+
</h2>
|
4
|
+
|
5
|
+
<p>
|
6
|
+
<%= link_to "Sign in to your account" %>
|
7
|
+
</p>
|
8
|
+
|
9
|
+
<%= form_with model: @user, url: credential_path(id: params[:id]), method: :patch do |form| %>
|
10
|
+
<%= render form %>
|
11
|
+
<%= form.button "Submit", name: nil %>
|
12
|
+
<% end %>
|
@@ -0,0 +1,8 @@
|
|
1
|
+
<div>
|
2
|
+
<%= form.label :email %>
|
3
|
+
<%= form.email_field :email, autocomplete: "email", required: true %>
|
4
|
+
</div>
|
5
|
+
<div>
|
6
|
+
<%= form.label :password_challenge, "Current password" %>
|
7
|
+
<%= form.password_field :password_challenge, autocomplete: "current-password", required: true %>
|
8
|
+
</div>
|
@@ -10,11 +10,6 @@
|
|
10
10
|
<% end %>
|
11
11
|
|
12
12
|
<%= form_with model: @user, url: email_path, method: :patch do |form| %>
|
13
|
-
<%= form
|
14
|
-
<%= form.email_field :email, autocomplete: "email", required: true %>
|
15
|
-
|
16
|
-
<%= form.label :password_challenge, "Current password" %>
|
17
|
-
<%= form.password_field :password_challenge, autocomplete: "current-password", required: true %>
|
18
|
-
|
13
|
+
<%= render form %>
|
19
14
|
<%= form.button "Submit", name: nil %>
|
20
15
|
<% end %>
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<div>
|
2
|
+
<%= form.label :password_challenge, "Current password" %>
|
3
|
+
<%= form.password_field :password_challenge, autocomplete: "current-password", required: true %>
|
4
|
+
</div>
|
5
|
+
<div>
|
6
|
+
<%= form.label :password %>
|
7
|
+
<%= form.password_field :password, autocomplete: "new-password", required: true %>
|
8
|
+
</div>
|
9
|
+
<div>
|
10
|
+
<%= form.label :password_confirmation %>
|
11
|
+
<%= form.password_field :password_confirmation, autocomplete: "new-password", required: true %>
|
12
|
+
</div>
|
@@ -3,14 +3,6 @@
|
|
3
3
|
</h2>
|
4
4
|
|
5
5
|
<%= form_with model: @user, url: password_path, method: :patch do |form| %>
|
6
|
-
<%= form
|
7
|
-
<%= form.password_field :password_challenge, autocomplete: "current-password", required: true %>
|
8
|
-
|
9
|
-
<%= form.label :password %>
|
10
|
-
<%= form.password_field :password, autocomplete: "new-password", required: true %>
|
11
|
-
|
12
|
-
<%= form.label :password_confirmation %>
|
13
|
-
<%= form.password_field :password_confirmation, autocomplete: "new-password", required: true %>
|
14
|
-
|
6
|
+
<%= render form %>
|
15
7
|
<%= form.button "Submit", name: nil %>
|
16
8
|
<% end %>
|
@@ -6,9 +6,7 @@
|
|
6
6
|
<%= link_to "Sign in to your account", new_session_path %>
|
7
7
|
</p>
|
8
8
|
|
9
|
-
<%= form_with url: recoveries_path do |form| %>
|
10
|
-
<%= form
|
11
|
-
<%= form.email_field :email, autofocus: true, autocomplete: "email", required: true %>
|
12
|
-
|
9
|
+
<%= form_with url: recoveries_path, scope: :user do |form| %>
|
10
|
+
<%= render form %>
|
13
11
|
<%= form.button "Submit", name: nil %>
|
14
12
|
<% end -%>
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<div>
|
2
|
+
<%= form.label :email %>
|
3
|
+
<%= form.email_field :email, autofocus: true, autocomplete: "email", required: true %>
|
4
|
+
</div>
|
5
|
+
<div>
|
6
|
+
<%= form.label :password %>
|
7
|
+
<%= form.password_field :password, autocomplete: "new-password", required: true %>
|
8
|
+
</div>
|
9
|
+
<div>
|
10
|
+
<%= form.label :password_confirmation %>
|
11
|
+
<%= form.password_field :password_confirmation, autocomplete: "new-password", required: true %>
|
12
|
+
</div>
|
@@ -7,17 +7,6 @@
|
|
7
7
|
</p>
|
8
8
|
|
9
9
|
<%= form_with model: @user, url: registrations_path do |form| %>
|
10
|
-
|
11
|
-
<%= form.label :email %>
|
12
|
-
<%= form.email_field :email, autofocus: true, autocomplete: "email", required: true %>
|
13
|
-
</div>
|
14
|
-
<div>
|
15
|
-
<%= form.label :password %>
|
16
|
-
<%= form.password_field :password, autocomplete: "new-password", required: true %>
|
17
|
-
</div>
|
18
|
-
<div>
|
19
|
-
<%= form.label :password_confirmation %>
|
20
|
-
<%= form.password_field :password_confirmation, autocomplete: "new-password", required: true %>
|
21
|
-
</div>
|
10
|
+
<%= render form %>
|
22
11
|
<%= form.button "Submit", name: nil %>
|
23
12
|
<% end %>
|
@@ -0,0 +1,8 @@
|
|
1
|
+
<div>
|
2
|
+
<%= form.label :email %>
|
3
|
+
<%= form.email_field :email, autofocus: true, autocomplete: "email", required: true %>
|
4
|
+
</div>
|
5
|
+
<div>
|
6
|
+
<%= form.label :password %>
|
7
|
+
<%= form.password_field :password, autocomplete: "current-password", required: true %>
|
8
|
+
</div>
|
@@ -7,9 +7,6 @@
|
|
7
7
|
</p>
|
8
8
|
|
9
9
|
<%= form_with model: @session do |form| %>
|
10
|
-
<%= form
|
11
|
-
<%= form.email_field :email, autofocus: true, autocomplete: "email", required: true %>
|
12
|
-
<%= form.label :password %>
|
13
|
-
<%= form.password_field :password, autocomplete: "current-password", required: true %>
|
10
|
+
<%= render form %>
|
14
11
|
<%= form.button "Submit", name: nil %>
|
15
12
|
<% end -%>
|
@@ -0,0 +1,45 @@
|
|
1
|
+
en:
|
2
|
+
avocado:
|
3
|
+
affirmations:
|
4
|
+
create:
|
5
|
+
success: Check email for sign in instructions.
|
6
|
+
errors:
|
7
|
+
invalid_token: Sign in link is invalid.
|
8
|
+
unverified_email: Verify email first before signing in.
|
9
|
+
update:
|
10
|
+
success: Signed in successfully.
|
11
|
+
credentials:
|
12
|
+
update:
|
13
|
+
success: Password reset successfully.
|
14
|
+
errors:
|
15
|
+
invalid_token: Password reset link is invalid.
|
16
|
+
emails:
|
17
|
+
update:
|
18
|
+
success: Email has been changed.
|
19
|
+
filters:
|
20
|
+
invalid_password_challenge: Password challenge failed.
|
21
|
+
passwords:
|
22
|
+
update:
|
23
|
+
success: Password has been changed.
|
24
|
+
recoveries:
|
25
|
+
create:
|
26
|
+
success: Check email for reset instructions.
|
27
|
+
errors:
|
28
|
+
unverified_email: Verify email first before resetting password.
|
29
|
+
registrations:
|
30
|
+
create:
|
31
|
+
success: Registration successful.
|
32
|
+
sessions:
|
33
|
+
create:
|
34
|
+
success: Session created.
|
35
|
+
destroy:
|
36
|
+
success: Session destroyed.
|
37
|
+
errors:
|
38
|
+
authentication: Authentication failed.
|
39
|
+
verifications:
|
40
|
+
create:
|
41
|
+
success: Verification email sent.
|
42
|
+
errors:
|
43
|
+
invalid_token: Email verification link is invalid.
|
44
|
+
update:
|
45
|
+
success: Email address verified.
|
@@ -0,0 +1,11 @@
|
|
1
|
+
scope module: :avocado do
|
2
|
+
resource :email, only: %i[edit update]
|
3
|
+
resource :password, only: %i[edit update]
|
4
|
+
resources :affirmations, only: %i[new create edit update]
|
5
|
+
resources :credentials, only: %i[edit update]
|
6
|
+
resources :events, only: %i[index]
|
7
|
+
resources :recoveries, only: %i[new create]
|
8
|
+
resources :registrations, only: %i[new create]
|
9
|
+
resources :sessions, only: %i[index new create destroy]
|
10
|
+
resources :verifications, only: %i[create edit update]
|
11
|
+
end
|
data/config.ru
CHANGED
data/docs/USAGE.md
ADDED
@@ -0,0 +1,164 @@
|
|
1
|
+
# Overview
|
2
|
+
|
3
|
+
The 🥑 gem is a [Rails Engine] composed of a mixture of Ruby modules that get
|
4
|
+
included into application classes and Ruby classes which will run directly from
|
5
|
+
the 🥑 gem itself. The classes are intended to provide good defaults for basic
|
6
|
+
scenarios, and can be subclassed and overridden for special cases.
|
7
|
+
|
8
|
+
## Requirements
|
9
|
+
|
10
|
+
Apps must be running Rails 7.1 or newer. The 🥑 gem uses features like
|
11
|
+
`authenticate_by`, the `password_challenge` feature of `has_secure_password`,
|
12
|
+
`generates_token_for`, and `normalizes` which don't exist in earlier versions.
|
13
|
+
|
14
|
+
The database schema must have columns that match the `users`, `sessions`, and
|
15
|
+
`events` tables from the [demo app schema]. More columns in each table are
|
16
|
+
acceptable; the demo is just a minimum. Slight variations (using `uuid` instead
|
17
|
+
of `bigint` for example) are harmless, but large departures will break the
|
18
|
+
integration.
|
19
|
+
|
20
|
+
Run `bin/rails g avocado:migrations` to generate migrations for the tables.
|
21
|
+
|
22
|
+
The application must also have:
|
23
|
+
|
24
|
+
- An `ApplicationController` base controller class for the controllers to
|
25
|
+
inherit from.
|
26
|
+
- An `ApplicationMailer` base mailer class which sets a layout and default
|
27
|
+
`from` value.
|
28
|
+
- A `root_path` route helper method (typically generated by routes configured in
|
29
|
+
the application).
|
30
|
+
|
31
|
+
## Usage
|
32
|
+
|
33
|
+
### Models
|
34
|
+
|
35
|
+
Include these modules into `ActiveRecord` model classes:
|
36
|
+
|
37
|
+
```ruby
|
38
|
+
class User < ApplicationRecord
|
39
|
+
include Avocado::User
|
40
|
+
end
|
41
|
+
|
42
|
+
class Session < ApplicationRecord
|
43
|
+
include Avocado::Session
|
44
|
+
end
|
45
|
+
|
46
|
+
class Event < ApplicationRecord
|
47
|
+
include Avocado::Event
|
48
|
+
end
|
49
|
+
```
|
50
|
+
|
51
|
+
This will set up some basic associations, validations, callbacks, and
|
52
|
+
normalizations for those models.
|
53
|
+
|
54
|
+
### Controllers
|
55
|
+
|
56
|
+
Add the `Avocado::Authentication` module to the top-level controller:
|
57
|
+
|
58
|
+
```ruby
|
59
|
+
class ApplicationController < ActionController::Base
|
60
|
+
include Avocado::Authentication
|
61
|
+
end
|
62
|
+
```
|
63
|
+
|
64
|
+
### Routes
|
65
|
+
|
66
|
+
By defalt, 🥑 does not add any routes to the application when initialized. To
|
67
|
+
hook up the controllers to routes, they must be added to the `config/routes.rb`
|
68
|
+
of the application. It's possible to add all of the routes, or just a subset.
|
69
|
+
|
70
|
+
This example defines a `root` route and also pulls in every feature route:
|
71
|
+
|
72
|
+
```ruby
|
73
|
+
Rails.application.routes.draw do
|
74
|
+
root to: "records#index"
|
75
|
+
draw(🥑)
|
76
|
+
end
|
77
|
+
```
|
78
|
+
|
79
|
+
This example defines a `root` route and adds only a subset of feature routes:
|
80
|
+
|
81
|
+
```ruby
|
82
|
+
Rails.application.routes.draw do
|
83
|
+
root to: "records#index"
|
84
|
+
scope module: 🥑 do
|
85
|
+
resources :registrations, only: %i[new create]
|
86
|
+
resources :sessions, only: %i[new create destroy]
|
87
|
+
end
|
88
|
+
end
|
89
|
+
```
|
90
|
+
|
91
|
+
## Summary
|
92
|
+
|
93
|
+
### Routable controller features
|
94
|
+
|
95
|
+
The 🥑 gem will create REST-ful routes that go to the various controllers during
|
96
|
+
app initialization.
|
97
|
+
|
98
|
+
These external (unauthenticated) features are available:
|
99
|
+
|
100
|
+
- `Registrations` -- Fill out new user form and create users
|
101
|
+
- `Sessions` -- Sign in and sign out
|
102
|
+
- `Recoveries` -- Triggers password reset via emailed expiring link
|
103
|
+
- `Credentials` -- Use expiring token link from recovery to update password
|
104
|
+
- `Verifications` -- Confirm email address on account creation or email change
|
105
|
+
- `Affirmations` -- "Passwordless" authentication via emailed expiring link
|
106
|
+
|
107
|
+
These internal (authenticated) features are available:
|
108
|
+
|
109
|
+
- `Sessions` -- Index view of active sessions, ability to destroy sessions
|
110
|
+
- `Events` -- Index view of the user activity audit log
|
111
|
+
- `Passwords` -- Edit and update a user password
|
112
|
+
- `Emails` -- Edit and update a user email
|
113
|
+
|
114
|
+
Linking to any of these internal pages is optional. Apps can use them as-is,
|
115
|
+
override their views, or even ignore them entirely and make local versions.
|
116
|
+
|
117
|
+
### Mailers
|
118
|
+
|
119
|
+
There is an `Avocado::Mailer` which gets called to send emails. The mailer views
|
120
|
+
here are very basic, and should be overriden within applications. Place views
|
121
|
+
within `app/views/avocado/mailer/` to make this happen.
|
122
|
+
|
123
|
+
### Before actions
|
124
|
+
|
125
|
+
There is an `authenticate` method installed as default controller behavior using
|
126
|
+
`before_action :authenticate`. Any actions which do not need to be authenticated
|
127
|
+
should disable this with `skip_before_action :authenticate`, or inherit from a
|
128
|
+
controller which performs the skip.
|
129
|
+
|
130
|
+
There is also a `set_current_request_details` method installed as a default
|
131
|
+
`before_action` which takes some loggable request meta information (User Agent,
|
132
|
+
IP Address) and sets their values in `Current` so that they are accesible to
|
133
|
+
code elsewhere in the 🥑 gem.
|
134
|
+
|
135
|
+
### Helpers
|
136
|
+
|
137
|
+
The `Avocado::Authentication` module included into the application controller
|
138
|
+
provides some helper methods available in controllers, views, and helpers:
|
139
|
+
|
140
|
+
- `signed_in?` is true if the session has a signed in user
|
141
|
+
- `current_session` provides the DB record for the session, if one exists
|
142
|
+
- `current_user` returns the user belonging to that session
|
143
|
+
|
144
|
+
Usage of these can be seen in the views in the [demo app].
|
145
|
+
|
146
|
+
## Customization
|
147
|
+
|
148
|
+
There is not any configuration. To override functionality:
|
149
|
+
|
150
|
+
- Redefine a method created in one of the models by the included module
|
151
|
+
- Subclass a controller and update the routing to go to the subclass
|
152
|
+
- Place views in the app where avocado expects (`app/views/avocado`) them to
|
153
|
+
override the defaults
|
154
|
+
|
155
|
+
There is an `avocado:views` generator which will copy all the views as a
|
156
|
+
starting point for further modification.
|
157
|
+
|
158
|
+
## Examples
|
159
|
+
|
160
|
+
There is a [demo app] used by the specs which has some example usage.
|
161
|
+
|
162
|
+
[demo app schema]: https://github.com/tcuwp/avocado/blob/main/spec/internal/db/schema.rb
|
163
|
+
[demo app]: https://github.com/tcuwp/avocado/blob/main/spec/internal
|
164
|
+
[Rails Engine]: https://guides.rubyonrails.org/engines.html#what-are-engines-questionmark
|
@@ -1,5 +1,3 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
1
|
module Avocado
|
4
2
|
module Authentication
|
5
3
|
extend ActiveSupport::Concern
|
@@ -37,12 +35,12 @@ module Avocado
|
|
37
35
|
|
38
36
|
def sign_in(user)
|
39
37
|
::Session.create!(user: user).tap do |session|
|
40
|
-
cookies.signed.permanent[:session_token] = {value: session.
|
38
|
+
cookies.signed.permanent[:session_token] = {value: session.token, httponly: true}
|
41
39
|
end
|
42
40
|
end
|
43
41
|
|
44
42
|
def session_from_token
|
45
|
-
::Session.
|
43
|
+
::Session.find_by_token(cookies.signed[:session_token])
|
46
44
|
end
|
47
45
|
|
48
46
|
def set_current_request_details
|
data/lib/avocado/current.rb
CHANGED
data/lib/avocado/engine.rb
CHANGED
@@ -1,9 +1,12 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
1
|
require "avocado"
|
4
2
|
require "rails/engine"
|
5
3
|
|
6
4
|
module Avocado
|
7
5
|
class Engine < Rails::Engine
|
6
|
+
initializer :avocado_routing do
|
7
|
+
ActiveSupport.on_load(:action_dispatch_request) do
|
8
|
+
ActionDispatch::Routing::Mapper.define_method(:🥑) { :avocado }
|
9
|
+
end
|
10
|
+
end
|
8
11
|
end
|
9
12
|
end
|
data/lib/avocado/event.rb
CHANGED
data/lib/avocado/mailer.rb
CHANGED
data/lib/avocado/session.rb
CHANGED
@@ -1,14 +1,18 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
1
|
module Avocado
|
4
2
|
module Session
|
5
3
|
extend ActiveSupport::Concern
|
6
4
|
|
5
|
+
SECURE_TOKEN_LENGTH = 64
|
6
|
+
|
7
7
|
included do
|
8
8
|
include SessionCallbacks
|
9
9
|
|
10
|
+
has_secure_token length: SECURE_TOKEN_LENGTH, on: :initialize
|
11
|
+
|
10
12
|
belongs_to :user
|
11
13
|
|
14
|
+
validates :token, presence: true
|
15
|
+
|
12
16
|
scope :newest_first, -> { order(created_at: :desc) }
|
13
17
|
scope :non_current, -> { where.not(id: Current.session) }
|
14
18
|
end
|
data/lib/avocado/user.rb
CHANGED
data/lib/avocado/user_tokens.rb
CHANGED
data/lib/avocado/version.rb
CHANGED
data/lib/avocado.rb
CHANGED