revise_auth-jets 0.2.1
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 +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +32 -0
- data/Rakefile +18 -0
- data/app/config/routes.rb +31 -0
- data/app/controllers/main_controller.rb +9 -0
- data/app/controllers/revise_auth/email_controller.rb +28 -0
- data/app/controllers/revise_auth/password_controller.rb +24 -0
- data/app/controllers/revise_auth/registrations_controller.rb +44 -0
- data/app/controllers/revise_auth/sessions_controller.rb +19 -0
- data/app/controllers/revise_auth_controller.rb +12 -0
- data/app/mailers/revise_auth/mailer.rb +8 -0
- data/app/views/main/authenticated.html.erb +16 -0
- data/app/views/main/index.html.erb +15 -0
- data/app/views/revise_auth/mailer/confirm_email.html.erb +7 -0
- data/app/views/revise_auth/registrations/edit.html.erb +71 -0
- data/app/views/revise_auth/registrations/new.html.erb +30 -0
- data/app/views/revise_auth/sessions/new.html.erb +17 -0
- data/config/locales/de.yml +16 -0
- data/config/locales/el.yml +16 -0
- data/config/locales/en.yml +16 -0
- data/config/locales/fr.yml +16 -0
- data/config/locales/nl.yml +16 -0
- data/config/locales/tr.yml +16 -0
- data/config/locales/zh-TW.yml +16 -0
- data/lib/generators/revise_auth/model_generator.rb +64 -0
- data/lib/generators/revise_auth/templates/README +5 -0
- data/lib/generators/revise_auth/views_generator.rb +38 -0
- data/lib/revise_auth/authentication.rb +64 -0
- data/lib/revise_auth/backports.rb +24 -0
- data/lib/revise_auth/current.rb +6 -0
- data/lib/revise_auth/engine.rb +18 -0
- data/lib/revise_auth/model.rb +37 -0
- data/lib/revise_auth/route_constraint.rb +15 -0
- data/lib/revise_auth/routes.rb +49 -0
- data/lib/revise_auth/version.rb +3 -0
- data/lib/revise_auth.rb +11 -0
- data/lib/tasks/revise_auth_tasks.rake +4 -0
- metadata +97 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 867f8d44bffd162dfeb8d75ed9c55b7b7afb687c655f8523bd5413ba76bcd8cd
|
4
|
+
data.tar.gz: c5ba8737f091102a67ca738593446ed3d238859b1ca365dc077ebc7c857a767f
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: db195a90a24feb5d13c96d48f441c16fe8fe1569f1f8e478e9010601be8dbc9e98f590905b77642f47319af0f3e57f303307d7893c991f6bd73f1fcd527167ab
|
7
|
+
data.tar.gz: 550ba5cea3dce8912526a108dfc1f883647dc86cf52a7ba5d638a07c3fcd895ad15f863b9b22dbda5f6f513d9634e027976f294f514b942fde1808a7b30eaf27
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2023 Chris Oliver
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# ReviseAuth
|
2
|
+
|
3
|
+
A pure Ruby on Jets authentication system like Devise.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
bundle add "revise_auth"
|
11
|
+
```
|
12
|
+
|
13
|
+
And then execute the following to generate a `User` model (optionally adding other fields such as `first_name` and `last_name`):
|
14
|
+
```bash
|
15
|
+
$ jetsg revise_auth:model User first_name last_name
|
16
|
+
$ jets db:migrate
|
17
|
+
$ jetsg revise_auth:views
|
18
|
+
```
|
19
|
+
|
20
|
+
## Usage
|
21
|
+
|
22
|
+
ReviseAuth is designed around a single `User` model.
|
23
|
+
|
24
|
+
### Roles / Other User Types
|
25
|
+
|
26
|
+
ReviseAuth only works with a single model to keep things simple. We recommend adding roles to handle other types of users.
|
27
|
+
|
28
|
+
You can accomplish this in a few different ways:
|
29
|
+
|
30
|
+
* A `roles` attribute on the `User` model
|
31
|
+
* The Rolify gem
|
32
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require "bundler/setup"
|
2
|
+
require "bundler/gem_tasks"
|
3
|
+
require "rake/testtask"
|
4
|
+
|
5
|
+
APP_RAKEFILE = File.expand_path("test/dummy/Rakefile", __dir__)
|
6
|
+
load "rails/tasks/engine.rake"
|
7
|
+
load "rails/tasks/statistics.rake"
|
8
|
+
|
9
|
+
desc "Run tests"
|
10
|
+
Rake::TestTask.new(:test) do |t|
|
11
|
+
t.libs << "lib"
|
12
|
+
t.libs << "test"
|
13
|
+
t.pattern = "test/**/*_test.rb"
|
14
|
+
t.verbose = true
|
15
|
+
t.warning = false
|
16
|
+
end
|
17
|
+
|
18
|
+
task default: :test
|
@@ -0,0 +1,31 @@
|
|
1
|
+
Jets.application.routes.draw do
|
2
|
+
root "main#index"
|
3
|
+
|
4
|
+
get "authenticated", to: "main#authenticated", as: :authenticated
|
5
|
+
|
6
|
+
scope module: :revise_auth do
|
7
|
+
|
8
|
+
get "sign_up", to: "registrations#new", as: :sign_up
|
9
|
+
post "sign_up", to: "registrations#create"
|
10
|
+
get "login", to: "sessions#new", as: :login
|
11
|
+
post "login", to: "sessions#create"
|
12
|
+
|
13
|
+
get "profile", to: "registrations#edit", as: :profile
|
14
|
+
patch "profile", to: "registrations#update"
|
15
|
+
delete "profile", to: "registrations#destroy"
|
16
|
+
patch "profile/email", to: "email#update"
|
17
|
+
get "profile/password", to: "registrations#edit", as: :profile_password
|
18
|
+
patch "profile/password", to: "password#update"
|
19
|
+
|
20
|
+
# Email confirmation
|
21
|
+
get "profile/email", to: "email#show", as: :profile_email
|
22
|
+
|
23
|
+
delete "logout", to: "sessions#delete"
|
24
|
+
end
|
25
|
+
|
26
|
+
# The jets/public#show controller can serve static utf8 content out of the public folder.
|
27
|
+
# Note, as part of the deploy process Jets uploads files in the public folder to s3
|
28
|
+
# and serves them out of s3 directly. S3 is well suited to serve static assets.
|
29
|
+
# More info here: https://rubyonjets.com/docs/extras/assets-serving/
|
30
|
+
any "*catchall", to: "jets/public#show"
|
31
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
class ReviseAuth::EmailController < ReviseAuthController
|
2
|
+
before_action :authenticate_user!, except: [:show]
|
3
|
+
|
4
|
+
# GET /profile/email?confirmation_token=abcdef
|
5
|
+
def show
|
6
|
+
if User.find_by_token_for(:email_verification, params[:confirmation_token])&.confirm_email_change
|
7
|
+
#flash[:notice] = I18n.t("revise_auth.email_confirmed")
|
8
|
+
redirect_to(user_signed_in? ? profile_path : root_path)
|
9
|
+
else
|
10
|
+
redirect_to root_path, alert: I18n.t("revise_auth.email_confirm_failed")
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def update
|
15
|
+
if current_user.update(email_params)
|
16
|
+
current_user.send_confirmation_instructions
|
17
|
+
#flash[:notice] = I18n.t("revise_auth.confirmation_email_sent", email: current_user.unconfirmed_email)
|
18
|
+
end
|
19
|
+
|
20
|
+
redirect_to profile_path
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def email_params
|
26
|
+
params.require(:user).permit(:unconfirmed_email)
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
class ReviseAuth::PasswordController < ReviseAuthController
|
2
|
+
before_action :validate_current_password, only: [:update]
|
3
|
+
|
4
|
+
def update
|
5
|
+
if current_user.update(password_params)
|
6
|
+
#flash[:notice] = I18n.t("revise_auth.password_changed")
|
7
|
+
end
|
8
|
+
|
9
|
+
redirect_to profile_path
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def password_params
|
15
|
+
params.require(:user).permit(:password, :password_confirmation)
|
16
|
+
end
|
17
|
+
|
18
|
+
def validate_current_password
|
19
|
+
unless current_user.authenticate(params[:current_password])
|
20
|
+
#flash[:alert] = I18n.t("revise_auth.incorrect_password")
|
21
|
+
render "revise_auth/registrations/edit", status: :unprocessable_entity
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
class ReviseAuth::RegistrationsController < ReviseAuthController
|
2
|
+
before_action :authenticate_user!, except: [:new, :create]
|
3
|
+
|
4
|
+
def new
|
5
|
+
@user = User.new
|
6
|
+
end
|
7
|
+
|
8
|
+
def create
|
9
|
+
@user = User.new(sign_up_params)
|
10
|
+
if @user.save
|
11
|
+
login(@user)
|
12
|
+
redirect_to root_path
|
13
|
+
else
|
14
|
+
render :new, status: :unprocessable_entity
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def edit
|
19
|
+
end
|
20
|
+
|
21
|
+
def update
|
22
|
+
if current_user.update(profile_params)
|
23
|
+
redirect_to profile_path, notice: I18n.t("revise_auth.account_updated")
|
24
|
+
else
|
25
|
+
render :edit, status: :unprocessable_entity
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def destroy
|
30
|
+
current_user.destroy
|
31
|
+
logout
|
32
|
+
redirect_to root_path, status: :see_other, alert: I18n.t("revise_auth.account_deleted")
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def sign_up_params
|
38
|
+
params.require(:user).permit(:name, :email, :password, :password_confirmation)
|
39
|
+
end
|
40
|
+
|
41
|
+
def profile_params
|
42
|
+
params.require(:user).permit(:name)
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
class ReviseAuth::SessionsController < ReviseAuthController
|
2
|
+
def new
|
3
|
+
end
|
4
|
+
|
5
|
+
def create
|
6
|
+
if (user = User.authenticate_by(email: params[:email], password: params[:password]))
|
7
|
+
login(user)
|
8
|
+
redirect_to root_path
|
9
|
+
else
|
10
|
+
#flash[:alert] = I18n.t("revise_auth.invalid_email_or_password")
|
11
|
+
render :new, status: :unprocessable_entity
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def delete
|
16
|
+
logout
|
17
|
+
redirect_back(fallback_location: root_path)
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'revise_auth'
|
2
|
+
class ReviseAuthController < ApplicationController
|
3
|
+
# Return true if it's a revise_auth_controller. false to all controllers unless
|
4
|
+
# the controllers defined inside revise_auth. Useful if you want to apply a before
|
5
|
+
# filter to all controllers, except the ones in revise_auth:
|
6
|
+
#
|
7
|
+
# before_action :authenticate_user!, except: :revise_auth_controller?
|
8
|
+
include ReviseAuth::Authentication
|
9
|
+
def revise_auth_controller?
|
10
|
+
is_a?(::ReviseAuthController)
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
<nav>
|
2
|
+
<%= link_to "Home", root_path %>
|
3
|
+
|
4
|
+
<% if user_signed_in? %>
|
5
|
+
<%= link_to "Profile", profile_path %>
|
6
|
+
<%= button_to "Log out", 'logout', method: :delete %>
|
7
|
+
<% else %>
|
8
|
+
<%= link_to "Sign Up", sign_up_path %>
|
9
|
+
<%= link_to "Log in", login_path %>
|
10
|
+
<% end %>
|
11
|
+
</nav>
|
12
|
+
|
13
|
+
<h1>Authenticated Route</h1>
|
14
|
+
|
15
|
+
<p>You can only access this route when authenticated.</p>
|
16
|
+
<p>Authenticated as <%= current_user.email %></p>
|
@@ -0,0 +1,15 @@
|
|
1
|
+
<h1>Revise Auth</h1>
|
2
|
+
<nav>
|
3
|
+
<%= link_to "Home", root_path %>
|
4
|
+
|
5
|
+
<% if user_signed_in? %>
|
6
|
+
<%= link_to "Profile", profile_path %>
|
7
|
+
<%= button_to "Log out", 'logout', method: :delete %>
|
8
|
+
<% else %>
|
9
|
+
<%= link_to "Sign Up", sign_up_path %>
|
10
|
+
<%= link_to "Log in", login_path %>
|
11
|
+
<% end %>
|
12
|
+
</nav>
|
13
|
+
<div>
|
14
|
+
<%= link_to "Authentication Required", authenticated_path %>
|
15
|
+
</div>
|
@@ -0,0 +1,71 @@
|
|
1
|
+
<h1>Profile</h1>
|
2
|
+
|
3
|
+
<%= form_with model: current_user, url: profile_email_path do |form| %>
|
4
|
+
<fieldset>
|
5
|
+
<legend>Change Email Address</legend>
|
6
|
+
|
7
|
+
<% if current_user.unconfirmed_email? %>
|
8
|
+
<p>Waiting for confirmation of <%= current_user.unconfirmed_email %></p>
|
9
|
+
<% end %>
|
10
|
+
|
11
|
+
<% if form.object.errors.any? %>
|
12
|
+
<ul>
|
13
|
+
<% form.object.errors.full_messages.each do |message| %>
|
14
|
+
<li><%= message %></li>
|
15
|
+
<% end %>
|
16
|
+
</ul>
|
17
|
+
<% end %>
|
18
|
+
|
19
|
+
<p>Your email address is: <%= current_user.email %>
|
20
|
+
<p>To change your email, we will send a confirmation email to your new address to complete the change.</p>
|
21
|
+
|
22
|
+
<div>
|
23
|
+
<%= form.label :unconfirmed_email, "Email address" %>
|
24
|
+
<%= form.email_field :unconfirmed_email, required: true %>
|
25
|
+
</div>
|
26
|
+
|
27
|
+
<div>
|
28
|
+
<%= form.button "Save Changes" %>
|
29
|
+
</div>
|
30
|
+
</fieldset>
|
31
|
+
<% end %>
|
32
|
+
|
33
|
+
<%= form_with model: current_user, url: profile_password_path do |form| %>
|
34
|
+
<fieldset>
|
35
|
+
<legend>Change Password</legend>
|
36
|
+
|
37
|
+
<% if form.object.errors.any? %>
|
38
|
+
<ul>
|
39
|
+
<% form.object.errors.full_messages.each do |message| %>
|
40
|
+
<li><%= message %></li>
|
41
|
+
<% end %>
|
42
|
+
</ul>
|
43
|
+
<% end %>
|
44
|
+
|
45
|
+
<div>
|
46
|
+
<%= label_tag :current_password %>
|
47
|
+
<%= password_field_tag :current_password, nil, required: true %>
|
48
|
+
</div>
|
49
|
+
|
50
|
+
<div>
|
51
|
+
<%= form.label :password, "New password" %>
|
52
|
+
<%= form.password_field :password, required: true %>
|
53
|
+
</div>
|
54
|
+
|
55
|
+
<div>
|
56
|
+
<%= form.label :password_confirmation %>
|
57
|
+
<%= form.password_field :password_confirmation, required: true %>
|
58
|
+
</div>
|
59
|
+
|
60
|
+
<div>
|
61
|
+
<%= form.button "Save Changes" %>
|
62
|
+
</div>
|
63
|
+
</fieldset>
|
64
|
+
<% end %>
|
65
|
+
|
66
|
+
<%= form_with url: profile_path, method: :delete do |form| %>
|
67
|
+
<fieldset>
|
68
|
+
<legend>Delete my account</legend>
|
69
|
+
<%= form.button "Delete account", data: { turbo_confirm: "Are you sure?" } %>
|
70
|
+
</fieldset>
|
71
|
+
<% end %>
|
@@ -0,0 +1,30 @@
|
|
1
|
+
<h1>Sign Up</h1>
|
2
|
+
|
3
|
+
<%= form_with local: true, model: @user, url: sign_up_path do |form| %>
|
4
|
+
<% if form.object.errors.any? %>
|
5
|
+
<ul>
|
6
|
+
<% form.object.errors.full_messages.each do |message| %>
|
7
|
+
<li><%= message %></li>
|
8
|
+
<% end %>
|
9
|
+
</ul>
|
10
|
+
<% end %>
|
11
|
+
|
12
|
+
<div>
|
13
|
+
<%= form.label :email %>
|
14
|
+
<%= form.email_field :email, required: true, autofocus: true %>
|
15
|
+
</div>
|
16
|
+
|
17
|
+
<div>
|
18
|
+
<%= form.label :password %>
|
19
|
+
<%= form.password_field :password, required: true %>
|
20
|
+
</div>
|
21
|
+
|
22
|
+
<div>
|
23
|
+
<%= form.label :password_confirmation %>
|
24
|
+
<%= form.password_field :password_confirmation, required: true %>
|
25
|
+
</div>
|
26
|
+
|
27
|
+
<div>
|
28
|
+
<%= form.button "Sign Up" %>
|
29
|
+
</div>
|
30
|
+
<% end %>
|
@@ -0,0 +1,17 @@
|
|
1
|
+
<h1>Log in</h1>
|
2
|
+
|
3
|
+
<%= form_with(url: login_path, local: true) do |form| %>
|
4
|
+
<div>
|
5
|
+
<%= form.label :email %>
|
6
|
+
<%= form.email_field :email, required: true, autofocus: true %>
|
7
|
+
</div>
|
8
|
+
|
9
|
+
<div>
|
10
|
+
<%= form.label :password %>
|
11
|
+
<%= form.password_field :password, required: true %>
|
12
|
+
</div>
|
13
|
+
|
14
|
+
<div>
|
15
|
+
<%= form.button "Login" %>
|
16
|
+
</div>
|
17
|
+
<% end %>
|
@@ -0,0 +1,16 @@
|
|
1
|
+
de:
|
2
|
+
revise_auth:
|
3
|
+
account_deleted: "Dein Account wurde gelöscht."
|
4
|
+
account_updated: "Account wurde erfolgreich aktualisiert."
|
5
|
+
|
6
|
+
invalid_email_or_password: "Ungültige Email oder Passwort."
|
7
|
+
sign_up_or_login: "Registrieren oder anmelden um fortzufahren."
|
8
|
+
|
9
|
+
# Password changes
|
10
|
+
password_changed: "Dein Passwort wurde erfolgreich geändert."
|
11
|
+
incorrect_password: "Das Passwort ist ungültig. Bitte versuche es erneut."
|
12
|
+
|
13
|
+
# Email confirmations
|
14
|
+
email_confirmed: "Deine Email wurde erfogreich bestätigt."
|
15
|
+
email_confirm_failed: "Email Adresse kann nicht bestätigt werden."
|
16
|
+
confirmation_email_sent: "Eine Bestätigungsemail wurde versandt an %{email}"
|
@@ -0,0 +1,16 @@
|
|
1
|
+
el:
|
2
|
+
revise_auth:
|
3
|
+
account_deleted: "Ο λογαριασμός σας έχει διαγραφεί."
|
4
|
+
account_updated: "Ο λογαριασμός σας έχει ενημερωθεί επιτυχώς."
|
5
|
+
|
6
|
+
invalid_email_or_password: "Μη έγκυρο email ή κωδικός πρόσβασης."
|
7
|
+
sign_up_or_login: "Εγγραφείτε ή συνδεθείτε για να συνεχίσετε."
|
8
|
+
|
9
|
+
# Password changes
|
10
|
+
password_changed: "Ο κωδικός πρόσβασής σας άλλαξε με επιτυχία."
|
11
|
+
incorrect_password: "Ο τρέχων κωδικός πρόσβασής σας είναι λανθασμένος. Παρακαλώ δοκιμάστε ξανά."
|
12
|
+
|
13
|
+
# Email confirmations
|
14
|
+
email_confirmed: "Η διεύθυνση email σας επιβεβαιώθηκε επιτυχώς."
|
15
|
+
email_confirm_failed: "Δεν είναι δυνατή η επιβεβαίωση της διεύθυνσης email."
|
16
|
+
confirmation_email_sent: "Ένα email επιβεβαίωσης έχει σταλεί στο %{email}"
|
@@ -0,0 +1,16 @@
|
|
1
|
+
en:
|
2
|
+
revise_auth:
|
3
|
+
account_deleted: "Your account has been deleted."
|
4
|
+
account_updated: "Account updated successfully."
|
5
|
+
|
6
|
+
invalid_email_or_password: "Invalid email or password."
|
7
|
+
sign_up_or_login: "Sign up or log in to continue."
|
8
|
+
|
9
|
+
# Password changes
|
10
|
+
password_changed: "Your password has been changed successfully."
|
11
|
+
incorrect_password: "Your current password is incorrect. Please try again."
|
12
|
+
|
13
|
+
# Email confirmations
|
14
|
+
email_confirmed: "Your email address has been successfully confirmed."
|
15
|
+
email_confirm_failed: "Unable to confirm email address."
|
16
|
+
confirmation_email_sent: "A confirmation email has been sent to %{email}"
|
@@ -0,0 +1,16 @@
|
|
1
|
+
fr:
|
2
|
+
revise_auth:
|
3
|
+
account_deleted: "Votre compte a été supprimé."
|
4
|
+
account_updated: "Votre compte a été mis à jour."
|
5
|
+
|
6
|
+
invalid_email_or_password: "Email ou mot de passe incorrect."
|
7
|
+
sign_up_or_login: "Vous devez être connecté ou vous enregistrer pour continuer."
|
8
|
+
|
9
|
+
# Password changes
|
10
|
+
password_changed: "Votre mot de passe a été mis à jour avec succès."
|
11
|
+
incorrect_password: "Mot de passe incorrect. Merci de réessayer"
|
12
|
+
|
13
|
+
# Email confirmations
|
14
|
+
email_confirmed: "Votre adresse email vient d'être confirmé."
|
15
|
+
email_confirm_failed: "Impossible de confirmer votre adresse email."
|
16
|
+
confirmation_email_sent: "Un email de confirmation vient d'être envoyé à %{email}"
|
@@ -0,0 +1,16 @@
|
|
1
|
+
nl:
|
2
|
+
revise_auth:
|
3
|
+
account_deleted: "Uw account is verwijderd."
|
4
|
+
account_updated: "Account succesvol bijgewerkt."
|
5
|
+
|
6
|
+
invalid_email_of_password: "Ongeldige e-mail of wachtwoord."
|
7
|
+
sign_up_or_login: "Aanmelden of inloggen om door te gaan."
|
8
|
+
|
9
|
+
# Password changes
|
10
|
+
password_changed: "Uw wachtwoord is succesvol gewijzigd."
|
11
|
+
incorrect_password: "Uw huidige wachtwoord is onjuist. Probeer het opnieuw."
|
12
|
+
|
13
|
+
# E-mail confirmations
|
14
|
+
email_confirmed: "Uw e-mailadres is succesvol bevestigd."
|
15
|
+
email_confirm_failed: "E-mailadres bevestigen niet mogelijk."
|
16
|
+
confirmation_email_sent: "Er is een bevestigingsmail verzonden naar %{email}"
|
@@ -0,0 +1,16 @@
|
|
1
|
+
tr:
|
2
|
+
revise_auth:
|
3
|
+
account_deleted: "Hesabınız silindi."
|
4
|
+
account_updated: "Hesap başarıyla güncellendi."
|
5
|
+
|
6
|
+
invalid_email_or_password: "Geçersiz e-posta veya şifre."
|
7
|
+
sign_up_or_login: "Devam etmek için kaydol veya giriş yap."
|
8
|
+
|
9
|
+
# Password changes
|
10
|
+
password_changed: "Şifreniz başarıyla güncellendi."
|
11
|
+
incorrect_password: "Şu anki şifreniz yanlış. Lütfen tekrar deneyiniz."
|
12
|
+
|
13
|
+
# Email confirmations
|
14
|
+
email_confirmed: "E-posta adresiniz başarıyla onaylandı."
|
15
|
+
email_confirm_failed: "E-posta adresi doğrulanamıyor."
|
16
|
+
confirmation_email_sent: "%{email} adresine onay e-postası gönderildi."
|
@@ -0,0 +1,16 @@
|
|
1
|
+
zh-TW:
|
2
|
+
revise_auth:
|
3
|
+
account_deleted: "您的帳號已經被刪除"
|
4
|
+
account_updated: "帳號更新成功"
|
5
|
+
|
6
|
+
invalid_email_or_password: "錯誤的信箱或是密碼"
|
7
|
+
sign_up_or_login: "需要註冊或是登入才能進行"
|
8
|
+
|
9
|
+
# Password changes
|
10
|
+
password_changed: "您的密碼已經成功地更新"
|
11
|
+
incorrect_password: "您現在輸入的密碼不正確, 請重新嘗試"
|
12
|
+
|
13
|
+
# Email confirmations
|
14
|
+
email_confirmed: "您的電子信箱已經成功地通過驗證"
|
15
|
+
email_confirm_failed: "無法驗證您的電子信箱"
|
16
|
+
confirmation_email_sent: "電子信箱驗證信已寄往 %{email}"
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module ReviseAuth
|
2
|
+
module Generators
|
3
|
+
class ModelGenerator < Rails::Generators::NamedBase
|
4
|
+
include Rails::Generators::ResourceHelpers
|
5
|
+
|
6
|
+
desc "Generates a model for authentication, default User"
|
7
|
+
|
8
|
+
source_root File.expand_path("templates", __dir__)
|
9
|
+
|
10
|
+
argument :name, required: false, default: "User"
|
11
|
+
argument :attributes, type: :array, default: [], banner: "field:type field:type"
|
12
|
+
|
13
|
+
def initialize(args, *options)
|
14
|
+
@original_attributes = args[1..] || []
|
15
|
+
super
|
16
|
+
end
|
17
|
+
|
18
|
+
def generate_model
|
19
|
+
model_attributess = model_attributes.join(', ').gsub(':index', '').gsub(',', '')
|
20
|
+
puts "jets g model #{name} #{model_attributess}"
|
21
|
+
system "jets g model #{name} #{model_attributess}"
|
22
|
+
#generate :model, name, *model_attributes
|
23
|
+
end
|
24
|
+
|
25
|
+
def add_revise_auth_model
|
26
|
+
prepend_to_file model_path, "require 'revise_auth'\n"
|
27
|
+
inject_into_class model_path, class_name, " include ReviseAuth::Model\n"
|
28
|
+
end
|
29
|
+
|
30
|
+
def add_uniq_to_email_index
|
31
|
+
puts migration_path
|
32
|
+
puts name.downcase.pluralize
|
33
|
+
insert_into_file migration_path, after: "#{name.downcase.pluralize}, :email", force: true do
|
34
|
+
", unique: true"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def done
|
39
|
+
readme "README" if behavior == :invoke
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def migration_path
|
45
|
+
@migration_path ||= Dir.glob(Jets.root.join("db/migrate/*")).max_by { |f| File.mtime(f) }
|
46
|
+
end
|
47
|
+
|
48
|
+
def model_path
|
49
|
+
@model_path ||= File.join("app", "models", "#{file_path}.rb")
|
50
|
+
end
|
51
|
+
|
52
|
+
def model_attributes
|
53
|
+
[
|
54
|
+
"email:string:index",
|
55
|
+
"password_digest:string",
|
56
|
+
"confirmation_token:string",
|
57
|
+
"confirmed_at:datetime",
|
58
|
+
"confirmation_sent_at:datetime",
|
59
|
+
"unconfirmed_email:string"
|
60
|
+
] + @original_attributes
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require "rails/generators"
|
2
|
+
|
3
|
+
module ReviseAuth
|
4
|
+
module Generators
|
5
|
+
class ViewsGenerator < Rails::Generators::Base
|
6
|
+
source_root File.expand_path("../../../..", __FILE__)
|
7
|
+
|
8
|
+
class_option :views, aliases: "-v", type: :array, desc: "Select specific view directories to generate (confirmations, passwords, registrations, sessions, unlocks, mailer)"
|
9
|
+
|
10
|
+
def copy_config
|
11
|
+
template "app/config/routes.rb", "config/routes.rb"
|
12
|
+
end
|
13
|
+
|
14
|
+
def copy_controllers
|
15
|
+
template "app/controllers/main_controller.rb", "app/controllers/main_controller.rb"
|
16
|
+
template "app/controllers/revise_auth_controller.rb", "app/controllers/revise_auth_controller.rb"
|
17
|
+
if options[:controllers]
|
18
|
+
options[:controllers].each do |directory|
|
19
|
+
directory "app/controllers/revise_auth/#{directory}"
|
20
|
+
end
|
21
|
+
else
|
22
|
+
directory "app/controllers/revise_auth"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def copy_views
|
27
|
+
if options[:views]
|
28
|
+
options[:views].each do |directory|
|
29
|
+
directory "app/views/revise_auth/#{directory}"
|
30
|
+
end
|
31
|
+
else
|
32
|
+
directory "app/views/revise_auth"
|
33
|
+
directory "app/views/main"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module ReviseAuth
|
2
|
+
module Authentication
|
3
|
+
# Provides methods for controllers and views for authentication
|
4
|
+
#
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
included do
|
8
|
+
helper_method :user_signed_in?
|
9
|
+
helper_method :current_user
|
10
|
+
end
|
11
|
+
|
12
|
+
# Returns a boolean whether the user is signed in or not
|
13
|
+
def user_signed_in?
|
14
|
+
!!current_user
|
15
|
+
end
|
16
|
+
|
17
|
+
# Authenticates the user if not already authenticated
|
18
|
+
# Returns a User or nil
|
19
|
+
def current_user
|
20
|
+
Current.user ||= authenticate_user
|
21
|
+
end
|
22
|
+
|
23
|
+
# Authenticates a user or redirects to the login page
|
24
|
+
def authenticate_user!
|
25
|
+
redirect_to login_path unless user_signed_in?
|
26
|
+
end
|
27
|
+
|
28
|
+
# Authenticates the current user
|
29
|
+
# - from session cookie
|
30
|
+
# - (future) from Authorization header
|
31
|
+
def authenticate_user
|
32
|
+
Current.user = authenticated_user_from_session
|
33
|
+
end
|
34
|
+
|
35
|
+
# Returns a user from session cookie
|
36
|
+
def authenticated_user_from_session
|
37
|
+
user_id = session[:user_id]
|
38
|
+
return unless user_id
|
39
|
+
User.find_by(id: user_id)
|
40
|
+
end
|
41
|
+
|
42
|
+
# Logs in the user
|
43
|
+
# - Set Current.user for the current request
|
44
|
+
# - Save a session cookie so the next request is authenticated
|
45
|
+
def login(user)
|
46
|
+
Current.user = user
|
47
|
+
reset_session
|
48
|
+
session[:user_id] = user.id
|
49
|
+
end
|
50
|
+
|
51
|
+
def logout
|
52
|
+
Current.user = nil
|
53
|
+
reset_session
|
54
|
+
end
|
55
|
+
|
56
|
+
def reset_session
|
57
|
+
if session && session.respond_to?(:destroy)
|
58
|
+
session.destroy
|
59
|
+
else
|
60
|
+
self.session = {}
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module ReviseAuth
|
2
|
+
module Backports
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
class_methods do
|
6
|
+
# Prevent timing-based enumeration attacks.
|
7
|
+
# This can be removed when Rails 7.1 is released.
|
8
|
+
def authenticate_by(attributes)
|
9
|
+
passwords, identifiers = attributes.to_h.partition do |name, value|
|
10
|
+
!has_attribute?(name) && has_attribute?("#{name}_digest")
|
11
|
+
end.map(&:to_h)
|
12
|
+
|
13
|
+
raise ArgumentError, "One or more password arguments are required" if passwords.empty?
|
14
|
+
raise ArgumentError, "One or more finder arguments are required" if identifiers.empty?
|
15
|
+
if (record = find_by(identifiers))
|
16
|
+
record if passwords.count { |name, value| record.send(:"authenticate_#{name}", value) } == passwords.size
|
17
|
+
else
|
18
|
+
new(passwords)
|
19
|
+
nil
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module ReviseAuth
|
2
|
+
class Turbine < ::Jets::Turbine
|
3
|
+
initializer :revise_auth_controller do
|
4
|
+
ActiveSupport.on_load(:action_controller_base) do
|
5
|
+
include ReviseAuth::Authentication
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
# Set default session expiration of 30 days if not specified
|
10
|
+
# Runs immediately after Rails defines the default session store
|
11
|
+
# https://github.com/rails/rails/blob/7-0-stable/railties/lib/rails/application/finisher.rb#L43-L49
|
12
|
+
# initializer :revise_auth_cookie_session_expiry, after: :setup_default_session_store do |app|
|
13
|
+
# if Jets.config.session[:store] == ActionDispatch::Session::CookieStore
|
14
|
+
# app.config.session_options.with_defaults! expire_after: 30.days
|
15
|
+
# end
|
16
|
+
# end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module ReviseAuth
|
2
|
+
module Model
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
included do
|
6
|
+
include Backports
|
7
|
+
|
8
|
+
EMAIL_VERIFICATION_TOKEN_VALIDITY = 1.day
|
9
|
+
|
10
|
+
has_secure_password
|
11
|
+
has_secure_token :confirmation_token
|
12
|
+
|
13
|
+
# generates_token_for :email_verification, expires_in: EMAIL_VERIFICATION_TOKEN_VALIDITY do
|
14
|
+
# email
|
15
|
+
# end
|
16
|
+
|
17
|
+
validates :email, format: {with: URI::MailTo::EMAIL_REGEXP}, presence: true, uniqueness: true
|
18
|
+
validates :unconfirmed_email, format: {with: URI::MailTo::EMAIL_REGEXP}, allow_blank: true
|
19
|
+
validates_length_of :password, minimum: 6, allow_nil: true
|
20
|
+
|
21
|
+
before_validation do
|
22
|
+
email&.downcase!&.strip!
|
23
|
+
unconfirmed_email&.downcase!
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# Generates a confirmation token and send email to the user
|
28
|
+
def send_confirmation_instructions
|
29
|
+
token = generate_token_for(:email_verification)
|
30
|
+
ReviseAuth::Mailer.with(user: self, token: token).confirm_email.deliver_later
|
31
|
+
end
|
32
|
+
|
33
|
+
def confirm_email_change
|
34
|
+
update(confirmed_at: Time.current, email: unconfirmed_email)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
#module ActionDispatch::Routing
|
2
|
+
# class Mapper
|
3
|
+
# def revise_auth
|
4
|
+
# scope module: :revise_auth do
|
5
|
+
# revise_registration
|
6
|
+
|
7
|
+
# get "login", to: "sessions#new"
|
8
|
+
# post "login", to: "sessions#create"
|
9
|
+
|
10
|
+
# revise_profile
|
11
|
+
|
12
|
+
# patch "profile/email", to: "email#update"
|
13
|
+
# patch "profile/password", to: "password#update"
|
14
|
+
|
15
|
+
# # Email confirmation
|
16
|
+
# get "profile/email", to: "email#show"
|
17
|
+
|
18
|
+
# delete "logout", to: "sessions#destroy"
|
19
|
+
# end
|
20
|
+
# end
|
21
|
+
|
22
|
+
# # Adds helpers for config/routes.rb to constraint routes with authentication
|
23
|
+
# #
|
24
|
+
# def authenticated
|
25
|
+
# constraints ->(request) { ReviseAuth::RouteConstraint.new(request).user_signed_in? } do
|
26
|
+
# yield
|
27
|
+
# end
|
28
|
+
# end
|
29
|
+
|
30
|
+
# def unauthenticated
|
31
|
+
# constraints ->(request) { !ReviseAuth::RouteConstraint.new(request).user_signed_in? } do
|
32
|
+
# yield
|
33
|
+
# end
|
34
|
+
# end
|
35
|
+
|
36
|
+
# private
|
37
|
+
|
38
|
+
# def revise_registration
|
39
|
+
# get "sign_up", to: "registrations#new"
|
40
|
+
# post "sign_up", to: "registrations#create"
|
41
|
+
# end
|
42
|
+
|
43
|
+
# def revise_profile
|
44
|
+
# get "profile", to: "registrations#edit"
|
45
|
+
# patch "profile", to: "registrations#update"
|
46
|
+
# delete "profile", to: "registrations#destroy"
|
47
|
+
# end
|
48
|
+
# end
|
49
|
+
#end
|
data/lib/revise_auth.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
require "revise_auth/version"
|
2
|
+
require "revise_auth/engine"
|
3
|
+
require "revise_auth/routes"
|
4
|
+
|
5
|
+
module ReviseAuth
|
6
|
+
autoload :Authentication, "revise_auth/authentication"
|
7
|
+
autoload :Backports, "revise_auth/backports"
|
8
|
+
autoload :Current, "revise_auth/current"
|
9
|
+
autoload :Model, "revise_auth/model"
|
10
|
+
autoload :RouteConstraint, "revise_auth/route_constraint"
|
11
|
+
end
|
metadata
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: revise_auth-jets
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jeremiah Parrack
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2023-09-12 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bcrypt
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '3.1'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '3.1'
|
27
|
+
description: Authentication for Ruby on Jets apps
|
28
|
+
email:
|
29
|
+
- jeremiahlukus1@gmail.com
|
30
|
+
executables: []
|
31
|
+
extensions: []
|
32
|
+
extra_rdoc_files: []
|
33
|
+
files:
|
34
|
+
- MIT-LICENSE
|
35
|
+
- README.md
|
36
|
+
- Rakefile
|
37
|
+
- app/config/routes.rb
|
38
|
+
- app/controllers/main_controller.rb
|
39
|
+
- app/controllers/revise_auth/email_controller.rb
|
40
|
+
- app/controllers/revise_auth/password_controller.rb
|
41
|
+
- app/controllers/revise_auth/registrations_controller.rb
|
42
|
+
- app/controllers/revise_auth/sessions_controller.rb
|
43
|
+
- app/controllers/revise_auth_controller.rb
|
44
|
+
- app/mailers/revise_auth/mailer.rb
|
45
|
+
- app/views/main/authenticated.html.erb
|
46
|
+
- app/views/main/index.html.erb
|
47
|
+
- app/views/revise_auth/mailer/confirm_email.html.erb
|
48
|
+
- app/views/revise_auth/registrations/edit.html.erb
|
49
|
+
- app/views/revise_auth/registrations/new.html.erb
|
50
|
+
- app/views/revise_auth/sessions/new.html.erb
|
51
|
+
- config/locales/de.yml
|
52
|
+
- config/locales/el.yml
|
53
|
+
- config/locales/en.yml
|
54
|
+
- config/locales/fr.yml
|
55
|
+
- config/locales/nl.yml
|
56
|
+
- config/locales/tr.yml
|
57
|
+
- config/locales/zh-TW.yml
|
58
|
+
- lib/generators/revise_auth/model_generator.rb
|
59
|
+
- lib/generators/revise_auth/templates/README
|
60
|
+
- lib/generators/revise_auth/views_generator.rb
|
61
|
+
- lib/revise_auth.rb
|
62
|
+
- lib/revise_auth/authentication.rb
|
63
|
+
- lib/revise_auth/backports.rb
|
64
|
+
- lib/revise_auth/current.rb
|
65
|
+
- lib/revise_auth/engine.rb
|
66
|
+
- lib/revise_auth/model.rb
|
67
|
+
- lib/revise_auth/route_constraint.rb
|
68
|
+
- lib/revise_auth/routes.rb
|
69
|
+
- lib/revise_auth/version.rb
|
70
|
+
- lib/tasks/revise_auth_tasks.rake
|
71
|
+
homepage: https://github.com/jeremiahlukus/revise_auth-jets
|
72
|
+
licenses:
|
73
|
+
- MIT
|
74
|
+
metadata:
|
75
|
+
homepage_uri: https://github.com/jeremiahlukus/revise_auth-jets
|
76
|
+
source_code_uri: https://github.com/jeremiahlukus/revise_auth-jets
|
77
|
+
changelog_uri: https://github.com/jeremiahlukus/revise_auth-jets/blob/main/CHANGELOG.md
|
78
|
+
post_install_message:
|
79
|
+
rdoc_options: []
|
80
|
+
require_paths:
|
81
|
+
- lib
|
82
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
83
|
+
requirements:
|
84
|
+
- - ">="
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
version: '0'
|
87
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
88
|
+
requirements:
|
89
|
+
- - ">="
|
90
|
+
- !ruby/object:Gem::Version
|
91
|
+
version: '0'
|
92
|
+
requirements: []
|
93
|
+
rubygems_version: 3.4.1
|
94
|
+
signing_key:
|
95
|
+
specification_version: 4
|
96
|
+
summary: Simple authentication for Ruby on Jets apps
|
97
|
+
test_files: []
|