rails_mvp_authentication 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +28 -0
  4. data/Rakefile +8 -0
  5. data/app/assets/config/rails_mvp_authentication_manifest.js +1 -0
  6. data/app/assets/stylesheets/rails_mvp_authentication/application.css +15 -0
  7. data/app/controllers/rails_mvp_authentication/application_controller.rb +4 -0
  8. data/app/helpers/rails_mvp_authentication/application_helper.rb +4 -0
  9. data/app/jobs/rails_mvp_authentication/application_job.rb +4 -0
  10. data/app/mailers/rails_mvp_authentication/application_mailer.rb +6 -0
  11. data/app/models/rails_mvp_authentication/application_record.rb +5 -0
  12. data/app/views/layouts/rails_mvp_authentication/application.html.erb +15 -0
  13. data/config/routes.rb +2 -0
  14. data/lib/generators/rails_mvp_authentication/USAGE +5 -0
  15. data/lib/generators/rails_mvp_authentication/install_generator.rb +251 -0
  16. data/lib/generators/rails_mvp_authentication/templates/README +7 -0
  17. data/lib/generators/rails_mvp_authentication/templates/authentication.rb.tt +58 -0
  18. data/lib/generators/rails_mvp_authentication/templates/confirmations_controller.rb.tt +32 -0
  19. data/lib/generators/rails_mvp_authentication/templates/current.rb.tt +3 -0
  20. data/lib/generators/rails_mvp_authentication/templates/passwords_controller.rb.tt +52 -0
  21. data/lib/generators/rails_mvp_authentication/templates/sessions_controller.rb.tt +30 -0
  22. data/lib/generators/rails_mvp_authentication/templates/test/controllers/active_sessions_controller_test.rb.tt +68 -0
  23. data/lib/generators/rails_mvp_authentication/templates/test/controllers/confirmations_controller_test.rb.tt +143 -0
  24. data/lib/generators/rails_mvp_authentication/templates/test/controllers/passwords_controller_test.rb.tt +119 -0
  25. data/lib/generators/rails_mvp_authentication/templates/test/controllers/sessions_controller_test.rb.tt +105 -0
  26. data/lib/generators/rails_mvp_authentication/templates/test/controllers/users_controller_test.rb.tt +150 -0
  27. data/lib/generators/rails_mvp_authentication/templates/test/integration/friendly_redirects_test.rb.tt +23 -0
  28. data/lib/generators/rails_mvp_authentication/templates/test/integration/user_interface_test.rb.tt +35 -0
  29. data/lib/generators/rails_mvp_authentication/templates/test/mailers/previews/user_mailer_preview.rb.tt +17 -0
  30. data/lib/generators/rails_mvp_authentication/templates/test/mailers/user_mailer_test.rb.tt +25 -0
  31. data/lib/generators/rails_mvp_authentication/templates/test/models/active_session_test.rb.tt +18 -0
  32. data/lib/generators/rails_mvp_authentication/templates/test/models/user_test.rb.tt +183 -0
  33. data/lib/generators/rails_mvp_authentication/templates/test/system/logins_test.rb.tt +18 -0
  34. data/lib/generators/rails_mvp_authentication/templates/user.rb.tt +96 -0
  35. data/lib/generators/rails_mvp_authentication/templates/user_mailer.rb.tt +22 -0
  36. data/lib/generators/rails_mvp_authentication/templates/users_controller.rb.tt +59 -0
  37. data/lib/generators/rails_mvp_authentication/templates/views/confirmations/new.html.erb.tt +4 -0
  38. data/lib/generators/rails_mvp_authentication/templates/views/passwords/edit.html.erb.tt +11 -0
  39. data/lib/generators/rails_mvp_authentication/templates/views/passwords/new.html.erb.tt +4 -0
  40. data/lib/generators/rails_mvp_authentication/templates/views/sessions/new.html.erb.tt +15 -0
  41. data/lib/generators/rails_mvp_authentication/templates/views/user_mailer/confirmation.html.erb.tt +3 -0
  42. data/lib/generators/rails_mvp_authentication/templates/views/user_mailer/confirmation.text.erb.tt +3 -0
  43. data/lib/generators/rails_mvp_authentication/templates/views/user_mailer/password_reset.html.erb.tt +3 -0
  44. data/lib/generators/rails_mvp_authentication/templates/views/user_mailer/password_reset.text.erb.tt +3 -0
  45. data/lib/generators/rails_mvp_authentication/templates/views/users/edit.html.erb.tt +42 -0
  46. data/lib/generators/rails_mvp_authentication/templates/views/users/new.html.erb.tt +16 -0
  47. data/lib/rails_mvp_authentication/engine.rb +5 -0
  48. data/lib/rails_mvp_authentication/version.rb +3 -0
  49. data/lib/rails_mvp_authentication.rb +6 -0
  50. data/lib/tasks/rails_mvp_authentication_tasks.rake +4 -0
  51. metadata +129 -0
@@ -0,0 +1,183 @@
1
+ require "test_helper"
2
+
3
+ class UserTest < ActiveSupport::TestCase
4
+ include ActionMailer::TestHelper
5
+
6
+ setup do
7
+ @user = User.new(email: "unique_email@example.com", password: "password", password_confirmation: "password")
8
+ end
9
+
10
+ test "should be valid" do
11
+ assert @user.valid?
12
+ end
13
+
14
+ test "should have email" do
15
+ @user.email = nil
16
+ assert_not @user.valid?
17
+ end
18
+
19
+ test "email should be unique" do
20
+ @user.save!
21
+ @invalid_user = User.new(email: @user.email)
22
+
23
+ assert_not @invalid_user.valid?
24
+ end
25
+
26
+ test "email should be saved as lowercase" do
27
+ email = "unique_email@example.com"
28
+
29
+ @user = User.new(email: email.upcase, password: "password", password_confirmation: "password")
30
+ @user.save!
31
+
32
+ assert_equal email.downcase, @user.email
33
+ end
34
+
35
+ test "email should be valid" do
36
+ invalid_emails = %w[foo foo@ foo@bar.]
37
+
38
+ invalid_emails.each do |invalid_email|
39
+ @user.email = invalid_email
40
+ assert_not @user.valid?
41
+ end
42
+ end
43
+
44
+ test "should respond to confirmed?" do
45
+ assert_not @user.confirmed?
46
+
47
+ @user.confirmed_at = Time.now
48
+
49
+ assert @user.confirmed?
50
+ end
51
+
52
+ test "should respond to unconfirmed?" do
53
+ assert @user.unconfirmed?
54
+
55
+ @user.confirmed_at = Time.now
56
+
57
+ assert_not @user.unconfirmed?
58
+ end
59
+
60
+ test "should respond to reconfirming?" do
61
+ assert_not @user.reconfirming?
62
+
63
+ @user.unconfirmed_email = "unconfirmed_email@example.com"
64
+
65
+ assert @user.reconfirming?
66
+ end
67
+
68
+ test "should respond to unconfirmed_or_reconfirming?" do
69
+ assert @user.unconfirmed_or_reconfirming?
70
+
71
+ @user.unconfirmed_email = "unconfirmed_email@example.com"
72
+ @user.confirmed_at = Time.now
73
+
74
+ assert @user.unconfirmed_or_reconfirming?
75
+ end
76
+
77
+ test "should send confirmation email" do
78
+ @user.save!
79
+
80
+ assert_emails 1 do
81
+ @user.send_confirmation_email!
82
+ end
83
+
84
+ assert_equal @user.email, ActionMailer::Base.deliveries.last.to[0]
85
+ end
86
+
87
+ test "should send confirmation email to unconfirmed_email" do
88
+ @user.save!
89
+ @user.update!(unconfirmed_email: "unconfirmed_email@example.com")
90
+
91
+ assert_emails 1 do
92
+ @user.send_confirmation_email!
93
+ end
94
+
95
+ assert_equal @user.unconfirmed_email, ActionMailer::Base.deliveries.last.to[0]
96
+ end
97
+
98
+ test "should respond to send_password_reset_email!" do
99
+ @user.save!
100
+
101
+ assert_emails 1 do
102
+ @user.send_password_reset_email!
103
+ end
104
+ end
105
+
106
+ test "should downcase unconfirmed_email" do
107
+ email = "UNCONFIRMED_EMAIL@EXAMPLE.COM"
108
+ @user.unconfirmed_email = email
109
+ @user.save!
110
+
111
+ assert_equal email.downcase, @user.unconfirmed_email
112
+ end
113
+
114
+ test "unconfirmed_email should be valid" do
115
+ invalid_emails = %w[foo foo@ foo@bar.]
116
+
117
+ invalid_emails.each do |invalid_email|
118
+ @user.unconfirmed_email = invalid_email
119
+ assert_not @user.valid?
120
+ end
121
+ end
122
+
123
+ test "unconfirmed_email does not need to be available" do
124
+ @user.save!
125
+ @user.unconfirmed_email = @user.email
126
+ assert @user.valid?
127
+ end
128
+
129
+ test ".confirm! should return false if already confirmed" do
130
+ @confirmed_user = User.new(email: "unique_email@example.com", password: "password", password_confirmation: "password", confirmed_at: Time.current)
131
+
132
+ assert_not @confirmed_user.confirm!
133
+ end
134
+
135
+ test ".confirm! should update email if reconfirming" do
136
+ @reconfirmed_user = User.new(email: "unique_email@example.com", password: "password", password_confirmation: "password", confirmed_at: 1.week.ago, unconfirmed_email: "unconfirmed_email@example.com")
137
+ new_email = @reconfirmed_user.unconfirmed_email
138
+
139
+ freeze_time do
140
+ @reconfirmed_user.confirm!
141
+
142
+ assert_equal new_email, @reconfirmed_user.reload.email
143
+ assert_nil @reconfirmed_user.reload.unconfirmed_email
144
+ assert_equal Time.current, @reconfirmed_user.reload.confirmed_at
145
+ end
146
+ end
147
+
148
+ test ".confirm! should not update email if already taken" do
149
+ @confirmed_user = User.create!(email: "user1@example.com", password: "password", password_confirmation: "password")
150
+ @reconfirmed_user = User.create!(email: "user2@example.com", password: "password", password_confirmation: "password", confirmed_at: 1.week.ago, unconfirmed_email: @confirmed_user.email)
151
+
152
+ freeze_time do
153
+ assert_not @reconfirmed_user.confirm!
154
+ end
155
+ end
156
+
157
+ test ".confirm! should set confirmed_at" do
158
+ @unconfirmed_user = User.create!(email: "unique_email@example.com", password: "password", password_confirmation: "password")
159
+
160
+ freeze_time do
161
+ @unconfirmed_user.confirm!
162
+
163
+ assert_equal Time.current, @unconfirmed_user.reload.confirmed_at
164
+ end
165
+ end
166
+
167
+ test "should create active session" do
168
+ @user.save!
169
+
170
+ assert_difference("@user.active_sessions.count", 1) do
171
+ @user.active_sessions.create!
172
+ end
173
+ end
174
+
175
+ test "should destroy associated active session when destryoed" do
176
+ @user.save!
177
+ @user.active_sessions.create!
178
+
179
+ assert_difference("@user.active_sessions.count", -1) do
180
+ @user.destroy!
181
+ end
182
+ end
183
+ end
@@ -0,0 +1,18 @@
1
+ require "application_system_test_case"
2
+
3
+ class LoginsTest < ApplicationSystemTestCase
4
+ setup do
5
+ @confirmed_user = User.create!(email: "confirmed_user@example.com", password: "password", password_confirmation: "password", confirmed_at: Time.current)
6
+ end
7
+
8
+ test "should login and create active session if confirmed" do
9
+ visit login_path
10
+
11
+ fill_in "Email", with: @confirmed_user.email
12
+ fill_in "Password", with: @confirmed_user.password
13
+ click_on "Sign In"
14
+
15
+ assert_not_nil @confirmed_user.active_sessions.last.user_agent
16
+ assert_not_nil @confirmed_user.active_sessions.last.ip_address
17
+ end
18
+ end
@@ -0,0 +1,96 @@
1
+ class User < ApplicationRecord
2
+ CONFIRMATION_TOKEN_EXPIRATION = 10.minutes
3
+ MAILER_FROM_EMAIL = "no-reply@example.com"
4
+ PASSWORD_RESET_TOKEN_EXPIRATION = 10.minutes
5
+
6
+ attr_accessor :current_password
7
+
8
+ has_secure_password
9
+
10
+ has_many :active_sessions, dependent: :destroy
11
+
12
+ before_save :downcase_email
13
+ before_save :downcase_unconfirmed_email
14
+
15
+ validates :email, format: {with: URI::MailTo::EMAIL_REGEXP}, presence: true, uniqueness: true
16
+ validates :unconfirmed_email, format: {with: URI::MailTo::EMAIL_REGEXP, allow_blank: true}
17
+
18
+ def self.authenticate_by(attributes)
19
+ passwords, identifiers = attributes.to_h.partition do |name, value|
20
+ !has_attribute?(name) && has_attribute?("#{name}_digest")
21
+ end.map(&:to_h)
22
+
23
+ raise ArgumentError, "One or more password arguments are required" if passwords.empty?
24
+ raise ArgumentError, "One or more finder arguments are required" if identifiers.empty?
25
+ if (record = find_by(identifiers))
26
+ record if passwords.count { |name, value| record.public_send(:"authenticate_#{name}", value) } == passwords.size
27
+ else
28
+ new(passwords)
29
+ nil
30
+ end
31
+ end
32
+
33
+ def confirm!
34
+ if unconfirmed_or_reconfirming?
35
+ if unconfirmed_email.present?
36
+ return false unless update(email: unconfirmed_email, unconfirmed_email: nil)
37
+ end
38
+ update_columns(confirmed_at: Time.current)
39
+ else
40
+ false
41
+ end
42
+ end
43
+
44
+ def confirmed?
45
+ confirmed_at.present?
46
+ end
47
+
48
+ def confirmable_email
49
+ if unconfirmed_email.present?
50
+ unconfirmed_email
51
+ else
52
+ email
53
+ end
54
+ end
55
+
56
+ def generate_confirmation_token
57
+ signed_id expires_in: CONFIRMATION_TOKEN_EXPIRATION, purpose: :confirm_email
58
+ end
59
+
60
+ def generate_password_reset_token
61
+ signed_id expires_in: PASSWORD_RESET_TOKEN_EXPIRATION, purpose: :reset_password
62
+ end
63
+
64
+ def send_confirmation_email!
65
+ confirmation_token = generate_confirmation_token
66
+ UserMailer.confirmation(self, confirmation_token).deliver_now
67
+ end
68
+
69
+ def send_password_reset_email!
70
+ password_reset_token = generate_password_reset_token
71
+ UserMailer.password_reset(self, password_reset_token).deliver_now
72
+ end
73
+
74
+ def reconfirming?
75
+ unconfirmed_email.present?
76
+ end
77
+
78
+ def unconfirmed?
79
+ !confirmed?
80
+ end
81
+
82
+ def unconfirmed_or_reconfirming?
83
+ unconfirmed? || reconfirming?
84
+ end
85
+
86
+ private
87
+
88
+ def downcase_email
89
+ self.email = email.downcase
90
+ end
91
+
92
+ def downcase_unconfirmed_email
93
+ return if unconfirmed_email.nil?
94
+ self.unconfirmed_email = unconfirmed_email.downcase
95
+ end
96
+ end
@@ -0,0 +1,22 @@
1
+ class UserMailer < ApplicationMailer
2
+ default from: User::MAILER_FROM_EMAIL
3
+
4
+ # Subject can be set in your I18n file at config/locales/en.yml
5
+ # with the following lookup:
6
+ #
7
+ # en.user_mailer.confirmation.subject
8
+ #
9
+ def confirmation(user, confirmation_token)
10
+ @user = user
11
+ @confirmation_token = confirmation_token
12
+
13
+ mail to: @user.confirmable_email, subject: "Confirmation Instructions"
14
+ end
15
+
16
+ def password_reset(user, password_reset_token)
17
+ @user = user
18
+ @password_reset_token = password_reset_token
19
+
20
+ mail to: @user.email, subject: "Password Reset Instructions"
21
+ end
22
+ end
@@ -0,0 +1,59 @@
1
+ class UsersController < ApplicationController
2
+ before_action :authenticate_user!, only: [:edit, :destroy, :update]
3
+ before_action :redirect_if_authenticated, only: [:create, :new]
4
+
5
+ def create
6
+ @user = User.new(create_user_params)
7
+ if @user.save
8
+ @user.send_confirmation_email!
9
+ redirect_to root_path, notice: "Please check your email for confirmation instructions."
10
+ else
11
+ render :new, status: :unprocessable_entity
12
+ end
13
+ end
14
+
15
+ def destroy
16
+ current_user.destroy
17
+ reset_session
18
+ redirect_to root_path, notice: "Your account has been deleted."
19
+ end
20
+
21
+ def edit
22
+ @user = current_user
23
+ @active_sessions = @user.active_sessions.order(created_at: :desc)
24
+ end
25
+
26
+ def new
27
+ @user = User.new
28
+ end
29
+
30
+ def update
31
+ @user = current_user
32
+ @active_sessions = @user.active_sessions.order(created_at: :desc)
33
+ if @user.authenticate(params[:user][:current_password])
34
+ if @user.update(update_user_params)
35
+ if params[:user][:unconfirmed_email].present?
36
+ @user.send_confirmation_email!
37
+ redirect_to root_path, notice: "Check your email for confirmation instructions."
38
+ else
39
+ redirect_to root_path, notice: "Account updated."
40
+ end
41
+ else
42
+ render :edit, status: :unprocessable_entity
43
+ end
44
+ else
45
+ flash.now[:error] = "Incorrect password"
46
+ render :edit, status: :unprocessable_entity
47
+ end
48
+ end
49
+
50
+ private
51
+
52
+ def create_user_params
53
+ params.require(:user).permit(:email, :password, :password_confirmation)
54
+ end
55
+
56
+ def update_user_params
57
+ params.require(:user).permit(:current_password, :password, :password_confirmation, :unconfirmed_email)
58
+ end
59
+ end
@@ -0,0 +1,4 @@
1
+ <%%= form_with model: @user, url: confirmations_path do |form| %>
2
+ <%%= form.email_field :email, required: true %>
3
+ <%%= form.submit "Confirm Email" %>
4
+ <%% end %>
@@ -0,0 +1,11 @@
1
+ <%%= form_with url: password_path(params[:password_reset_token]), scope: :user, method: :put do |form| %>
2
+ <div>
3
+ <%%= form.label :password %>
4
+ <%%= form.password_field :password, required: true %>
5
+ </div>
6
+ <div>
7
+ <%%= form.label :password_confirmation %>
8
+ <%%= form.password_field :password_confirmation, required: true %>
9
+ </div>
10
+ <%%= form.submit "Update Password" %>
11
+ <%% end %>
@@ -0,0 +1,4 @@
1
+ <%%= form_with url: passwords_path, scope: :user do |form| %>
2
+ <%%= form.email_field :email, required: true %>
3
+ <%%= form.submit "Reset Password" %>
4
+ <%% end %>
@@ -0,0 +1,15 @@
1
+ <%%= form_with url: login_path, scope: :user do |form| %>
2
+ <div>
3
+ <%%= form.label :email %>
4
+ <%%= form.email_field :email, required: true %>
5
+ </div>
6
+ <div>
7
+ <%%= form.label :password %>
8
+ <%%= form.password_field :password, required: true %>
9
+ </div>
10
+ <div>
11
+ <%%= form.label :remember_me %>
12
+ <%%= form.check_box :remember_me %>
13
+ </div>
14
+ <%%= form.submit "Sign In" %>
15
+ <%% end %>
@@ -0,0 +1,3 @@
1
+ <h1>Confirmation Instructions</h1>
2
+
3
+ <%%= link_to "Click here to confirm your email.", edit_confirmation_url(@confirmation_token) %>
@@ -0,0 +1,3 @@
1
+ Confirmation Instructions
2
+
3
+ <%%= edit_confirmation_url(@confirmation_token) %>
@@ -0,0 +1,3 @@
1
+ <h1>Password Reset Instructions</h1>
2
+
3
+ <%%= link_to "Click here to reset your password.", edit_password_url(@password_reset_token) %>
@@ -0,0 +1,3 @@
1
+ Password Reset Instructions
2
+
3
+ <%%= edit_password_url(@password_reset_token) %>
@@ -0,0 +1,42 @@
1
+ <%%= form_with model: @user, url: account_path, method: :put do |form| %>
2
+ <%%= render partial: "shared/form_errors", locals: { object: form.object } %>
3
+ <div>
4
+ <%%= form.label :email, "Current Email" %>
5
+ <%%= form.email_field :email, disabled: true %>
6
+ </div>
7
+ <div>
8
+ <%%= form.label :unconfirmed_email, "New Email" %>
9
+ <%%= form.text_field :unconfirmed_email %>
10
+ </div>
11
+ <div>
12
+ <%%= form.label :password, "Password (leave blank if you don't want to change it)" %>
13
+ <%%= form.password_field :password %>
14
+ </div>
15
+ <div>
16
+ <%%= form.label :password_confirmation %>
17
+ <%%= form.password_field :password_confirmation %>
18
+ </div>
19
+ <hr/>
20
+ <div>
21
+ <%%= form.label :current_password, "Current password (we need your current password to confirm your changes)" %>
22
+ <%%= form.password_field :current_password, required: true %>
23
+ </div>
24
+ <%%= form.submit "Update Account" %>
25
+ <%% end %>
26
+ <h2>Current Logins</h2>
27
+ <%% if @active_sessions.any? %>
28
+ <%%= button_to "Log out of all other sessions", destroy_all_active_sessions_path, method: :delete %>
29
+ <table>
30
+ <thead>
31
+ <tr>
32
+ <th>User Agent</th>
33
+ <th>IP Address</th>
34
+ <th>Signed In At</th>
35
+ <th>Sign Out</th>
36
+ </tr>
37
+ </thead>
38
+ <tbody>
39
+ <%%= render @active_sessions %>
40
+ </tbody>
41
+ </table>
42
+ <%% end %>
@@ -0,0 +1,16 @@
1
+ <%%= form_with model: @user, url: sign_up_path do |form| %>
2
+ <%%= render partial: "shared/form_errors", locals: { object: form.object } %>
3
+ <div>
4
+ <%%= form.label :email %>
5
+ <%%= form.email_field :email, required: true %>
6
+ </div>
7
+ <div>
8
+ <%%= form.label :password %>
9
+ <%%= form.password_field :password, required: true %>
10
+ </div>
11
+ <div>
12
+ <%%= form.label :password_confirmation %>
13
+ <%%= form.password_field :password_confirmation, required: true %>
14
+ </div>
15
+ <%%= form.submit "Sign Up" %>
16
+ <%% end %>
@@ -0,0 +1,5 @@
1
+ module RailsMvpAuthentication
2
+ class Engine < ::Rails::Engine
3
+ isolate_namespace RailsMvpAuthentication
4
+ end
5
+ end
@@ -0,0 +1,3 @@
1
+ module RailsMvpAuthentication
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,6 @@
1
+ require "rails_mvp_authentication/version"
2
+ require "rails_mvp_authentication/engine"
3
+
4
+ module RailsMvpAuthentication
5
+ # Your code goes here...
6
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :rails_mvp_authentication do
3
+ # # Task goes here
4
+ # end
metadata ADDED
@@ -0,0 +1,129 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rails_mvp_authentication
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Steve Polito
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2022-02-18 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 7.0.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 7.0.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: sprockets-rails
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '3.4'
34
+ - - ">="
35
+ - !ruby/object:Gem::Version
36
+ version: 3.4.2
37
+ type: :runtime
38
+ prerelease: false
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - "~>"
42
+ - !ruby/object:Gem::Version
43
+ version: '3.4'
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: 3.4.2
47
+ description: Rails authentication via a generator.
48
+ email:
49
+ - stevepolito@hey.com
50
+ executables: []
51
+ extensions: []
52
+ extra_rdoc_files: []
53
+ files:
54
+ - MIT-LICENSE
55
+ - README.md
56
+ - Rakefile
57
+ - app/assets/config/rails_mvp_authentication_manifest.js
58
+ - app/assets/stylesheets/rails_mvp_authentication/application.css
59
+ - app/controllers/rails_mvp_authentication/application_controller.rb
60
+ - app/helpers/rails_mvp_authentication/application_helper.rb
61
+ - app/jobs/rails_mvp_authentication/application_job.rb
62
+ - app/mailers/rails_mvp_authentication/application_mailer.rb
63
+ - app/models/rails_mvp_authentication/application_record.rb
64
+ - app/views/layouts/rails_mvp_authentication/application.html.erb
65
+ - config/routes.rb
66
+ - lib/generators/rails_mvp_authentication/USAGE
67
+ - lib/generators/rails_mvp_authentication/install_generator.rb
68
+ - lib/generators/rails_mvp_authentication/templates/README
69
+ - lib/generators/rails_mvp_authentication/templates/authentication.rb.tt
70
+ - lib/generators/rails_mvp_authentication/templates/confirmations_controller.rb.tt
71
+ - lib/generators/rails_mvp_authentication/templates/current.rb.tt
72
+ - lib/generators/rails_mvp_authentication/templates/passwords_controller.rb.tt
73
+ - lib/generators/rails_mvp_authentication/templates/sessions_controller.rb.tt
74
+ - lib/generators/rails_mvp_authentication/templates/test/controllers/active_sessions_controller_test.rb.tt
75
+ - lib/generators/rails_mvp_authentication/templates/test/controllers/confirmations_controller_test.rb.tt
76
+ - lib/generators/rails_mvp_authentication/templates/test/controllers/passwords_controller_test.rb.tt
77
+ - lib/generators/rails_mvp_authentication/templates/test/controllers/sessions_controller_test.rb.tt
78
+ - lib/generators/rails_mvp_authentication/templates/test/controllers/users_controller_test.rb.tt
79
+ - lib/generators/rails_mvp_authentication/templates/test/integration/friendly_redirects_test.rb.tt
80
+ - lib/generators/rails_mvp_authentication/templates/test/integration/user_interface_test.rb.tt
81
+ - lib/generators/rails_mvp_authentication/templates/test/mailers/previews/user_mailer_preview.rb.tt
82
+ - lib/generators/rails_mvp_authentication/templates/test/mailers/user_mailer_test.rb.tt
83
+ - lib/generators/rails_mvp_authentication/templates/test/models/active_session_test.rb.tt
84
+ - lib/generators/rails_mvp_authentication/templates/test/models/user_test.rb.tt
85
+ - lib/generators/rails_mvp_authentication/templates/test/system/logins_test.rb.tt
86
+ - lib/generators/rails_mvp_authentication/templates/user.rb.tt
87
+ - lib/generators/rails_mvp_authentication/templates/user_mailer.rb.tt
88
+ - lib/generators/rails_mvp_authentication/templates/users_controller.rb.tt
89
+ - lib/generators/rails_mvp_authentication/templates/views/confirmations/new.html.erb.tt
90
+ - lib/generators/rails_mvp_authentication/templates/views/passwords/edit.html.erb.tt
91
+ - lib/generators/rails_mvp_authentication/templates/views/passwords/new.html.erb.tt
92
+ - lib/generators/rails_mvp_authentication/templates/views/sessions/new.html.erb.tt
93
+ - lib/generators/rails_mvp_authentication/templates/views/user_mailer/confirmation.html.erb.tt
94
+ - lib/generators/rails_mvp_authentication/templates/views/user_mailer/confirmation.text.erb.tt
95
+ - lib/generators/rails_mvp_authentication/templates/views/user_mailer/password_reset.html.erb.tt
96
+ - lib/generators/rails_mvp_authentication/templates/views/user_mailer/password_reset.text.erb.tt
97
+ - lib/generators/rails_mvp_authentication/templates/views/users/edit.html.erb.tt
98
+ - lib/generators/rails_mvp_authentication/templates/views/users/new.html.erb.tt
99
+ - lib/rails_mvp_authentication.rb
100
+ - lib/rails_mvp_authentication/engine.rb
101
+ - lib/rails_mvp_authentication/version.rb
102
+ - lib/tasks/rails_mvp_authentication_tasks.rake
103
+ homepage: https://github.com/stevepolitodesign/rails_mvp_authentication
104
+ licenses:
105
+ - MIT
106
+ metadata:
107
+ homepage_uri: https://github.com/stevepolitodesign/rails_mvp_authentication
108
+ source_code_uri: https://github.com/stevepolitodesign/rails_mvp_authentication
109
+ changelog_uri: https://github.com/stevepolitodesign/rails_mvp_authentication/blob/main/CHANGELOG.md
110
+ post_install_message:
111
+ rdoc_options: []
112
+ require_paths:
113
+ - lib
114
+ required_ruby_version: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - ">="
117
+ - !ruby/object:Gem::Version
118
+ version: '0'
119
+ required_rubygems_version: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - ">="
122
+ - !ruby/object:Gem::Version
123
+ version: '0'
124
+ requirements: []
125
+ rubygems_version: 3.2.32
126
+ signing_key:
127
+ specification_version: 4
128
+ summary: Rails authentication via a generator.
129
+ test_files: []