Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Blog app] Milestone 7 - Authentication with Devise #7

Merged
merged 11 commits into from
Jul 13, 2023
2 changes: 2 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -76,3 +76,5 @@ group :test do
gem 'selenium-webdriver'
gem 'webdrivers'
end

gem 'devise', '~> 4.9'
14 changes: 14 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ GEM
addressable (2.8.4)
public_suffix (>= 2.0.2, < 6.0)
ast (2.4.2)
bcrypt (3.1.19)
bindex (0.8.1)
bootsnap (1.16.0)
msgpack (~> 1.2)
Expand All @@ -88,6 +89,12 @@ GEM
debug (1.7.1)
irb (>= 1.5.0)
reline (>= 0.3.1)
devise (4.9.2)
bcrypt (~> 3.0)
orm_adapter (~> 0.1)
railties (>= 4.1.0)
responders
warden (~> 1.2.3)
diff-lcs (1.5.0)
erubi (1.12.0)
globalid (1.1.0)
Expand Down Expand Up @@ -130,6 +137,7 @@ GEM
nio4r (2.5.9)
nokogiri (1.15.2-x64-mingw-ucrt)
racc (~> 1.4)
orm_adapter (0.5.0)
parallel (1.23.0)
parser (3.2.2.3)
ast (~> 2.4.1)
Expand Down Expand Up @@ -174,6 +182,9 @@ GEM
regexp_parser (2.8.1)
reline (0.3.5)
io-console (~> 0.5)
responders (3.1.0)
actionpack (>= 5.2)
railties (>= 5.2)
rexml (3.2.5)
rspec-core (3.12.2)
rspec-support (~> 3.12.0)
Expand Down Expand Up @@ -230,6 +241,8 @@ GEM
tzinfo-data (1.2023.3)
tzinfo (>= 1.0.0)
unicode-display_width (2.4.2)
warden (1.2.9)
rack (>= 2.0.9)
web-console (4.2.0)
actionview (>= 6.0.0)
activemodel (>= 6.0.0)
Expand All @@ -254,6 +267,7 @@ DEPENDENCIES
bootsnap
capybara
debug
devise (~> 4.9)
importmap-rails
jbuilder
pg (~> 1.1)
Expand Down
129 changes: 129 additions & 0 deletions app/assets/stylesheets/application.css
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@

a {
text-decoration: none;
color: black;
}

.user-bio {
Expand Down Expand Up @@ -148,6 +149,134 @@ button {
border-radius: 5px;
}

/* style the authentification pages */
.auth_pages {
display: flex;
flex-direction: column;
align-items: center;
gap: 1rem;
color: black;
font-size: large;
width: 50vw;
margin: 100px auto;
padding: 1rem;
background-color: #c4ddae;
border: 1px solid gray;
}

form {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 1rem;
width: 40vw;
margin: auto auto;
}

form input {
width: 30vw;
padding: 0.5rem;
}

.shared {
display: flex;
flex-direction: column-reverse;
gap: 0;
width: 30vw;
padding-bottom: 0.5rem;
}

.shared a {
color: black !important;
}

ul {
list-style: none;
}

.actions {
border: 1px solid #1e1d1d;
border-radius: 5px;
box-shadow: 1px 1px 1px 1px #1e1d1d;
}

.actions input {
cursor: pointer;
font-size: 16.5px;
}

.remember_me {
display: flex;
flex-direction: row;
justify-content: flex-start;
align-items: stretch;
gap: 0.5rem;
}

.remember_me input {
width: 1rem;
height: 1rem;
}

.auth_links {
display: flex;
flex-direction: row;
justify-content: flex-start;
align-items: center;
gap: 1rem;
width: 30vw;
margin: auto auto;
}

.auth_links a {
color: blue;
padding: 0.5rem;
box-shadow: #1e1d1d 1px 1px 1px 1px;
}

#error_explanation {
color: red;
font-size: large;
}

#error_explanation h2 {
font-size: large;
font-weight: normal;
}

.cancel_back {
display: flex;
flex-direction: row;
justify-content: space-around;
width: 50vw;
}

.cancel_account {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
gap: 1rem;
}

.cancel_back a {
color: rgb(104, 4, 235);
font-weight: bold;
}

.cancel_account .button_to {
width: 20vw;
}

.button_to button,
.button_to button a {
cursor: pointer;
padding: 5px;
font-size: 15px;
color: blue;
border: none;
}

.form-elements {
display: flex;
flex-direction: row;
Expand Down
11 changes: 9 additions & 2 deletions app/controllers/application_controller.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
class ApplicationController < ActionController::Base
def current_user
@current_user ||= User.first
before_action :authenticate_user!
before_action :configure_permitted_parameters, if: :devise_controller?

protected

def configure_permitted_parameters
devise_parameter_sanitizer.permit(:sign_up, keys: %i[name email password password_confirmation])
devise_parameter_sanitizer.permit(:account_update,
keys: %i[name email password password_confirmation current_password])
end
end
1 change: 0 additions & 1 deletion app/controllers/users_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,5 @@ def show
@user = User.find_by_id(params[:id])

redirect_to users_path if @user.nil?
@posts = @user.posts
end
end
4 changes: 4 additions & 0 deletions app/models/user.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable
has_many :posts, foreign_key: :author_id, dependent: :destroy
has_many :comments, foreign_key: :user_id, dependent: :destroy
has_many :likes, foreign_key: :user_id, dependent: :destroy
Expand Down
21 changes: 21 additions & 0 deletions app/views/devise/confirmations/new.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<div class='auth_pages'>

<h2>Resend confirmation instructions</h2>

<%= form_for(resource, as: resource_name, url: confirmation_path(resource_name), html: { method: :post }) do |f| %>

<div class="field">
<%= f.label :email %><br />
<%= f.email_field :email, autofocus: true, autocomplete: "email", value: (resource.pending_reconfirmation? ? resource.unconfirmed_email : resource.email) %>
</div>

<%= render "devise/shared/error_messages", resource: resource %>

<div class="actions">
<%= f.submit "Resend confirmation instructions" %>
</div>
<% end %>

<%= render "devise/shared/links" %>

</div>
5 changes: 5 additions & 0 deletions app/views/devise/mailer/confirmation_instructions.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<p>Welcome <%= @email %>!</p>

<p>You can confirm your account email through the link below:</p>

<p><%= link_to 'Confirm my account', confirmation_url(@resource, confirmation_token: @token) %></p>
7 changes: 7 additions & 0 deletions app/views/devise/mailer/email_changed.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<p>Hello <%= @email %>!</p>

<% if @resource.try(:unconfirmed_email?) %>
<p>We're contacting you to notify you that your email is being changed to <%= @resource.unconfirmed_email %>.</p>
<% else %>
<p>We're contacting you to notify you that your email has been changed to <%= @resource.email %>.</p>
<% end %>
3 changes: 3 additions & 0 deletions app/views/devise/mailer/password_change.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<p>Hello <%= @resource.email %>!</p>

<p>We're contacting you to notify you that your password has been changed.</p>
8 changes: 8 additions & 0 deletions app/views/devise/mailer/reset_password_instructions.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<p>Hello <%= @resource.email %>!</p>

<p>Someone has requested a link to change your password. You can do this through the link below.</p>

<p><%= link_to 'Change my password', edit_password_url(@resource, reset_password_token: @token) %></p>

<p>If you didn't request this, please ignore this email.</p>
<p>Your password won't change until you access the link above and create a new one.</p>
7 changes: 7 additions & 0 deletions app/views/devise/mailer/unlock_instructions.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<p>Hello <%= @resource.email %>!</p>

<p>Your account has been locked due to an excessive number of unsuccessful sign in attempts.</p>

<p>Click the link below to unlock your account:</p>

<p><%= link_to 'Unlock my account', unlock_url(@resource, unlock_token: @token) %></p>
30 changes: 30 additions & 0 deletions app/views/devise/passwords/edit.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<div class='auth_pages'>

<h2>Change your password</h2>

<%= form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :put }) do |f| %>
<%= f.hidden_field :reset_password_token %>

<div class="field">
<%= f.label :password, "New password" %><br />
<% if @minimum_password_length %>
<em>(<%= @minimum_password_length %> characters minimum)</em><br />
<% end %>
<%= f.password_field :password, autofocus: true, autocomplete: "new-password" %>
</div>

<div class="field">
<%= f.label :password_confirmation, "Confirm new password" %><br />
<%= f.password_field :password_confirmation, autocomplete: "new-password" %>
</div>

<%= render "devise/shared/error_messages", resource: resource %>

<div class="actions">
<%= f.submit "Change my password" %>
</div>
<% end %>

<%= render "devise/shared/links" %>

</div>
20 changes: 20 additions & 0 deletions app/views/devise/passwords/new.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<div class='auth_pages'>

<h2>Forgot your password?</h2>

<%= form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :post }) do |f| %>

<div class="field">
<%= f.label :email %><br />
<%= f.email_field :email, autofocus: true, autocomplete: "email" %>
</div>

<%= render "devise/shared/error_messages", resource: resource %>

<div class="actions">
<%= f.submit "Send me reset password instructions" %>
</div>
<% end %>

<%= render "devise/shared/links" %>
</div>
50 changes: 50 additions & 0 deletions app/views/devise/registrations/edit.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<div class='auth_pages'>

<h2>Edit <%= resource_name.to_s.humanize %></h2>

<%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put }) do |f| %>

<div class="field">
<%= f.label :email %><br />
<%= f.email_field :email, autofocus: true, autocomplete: "email" %>
</div>

<% if devise_mapping.confirmable? && resource.pending_reconfirmation? %>
<div>Currently waiting confirmation for: <%= resource.unconfirmed_email %></div>
<% end %>

<div class="field">
<%= f.label :password %> <i>(leave blank if you don't want to change it)</i><br />
<%= f.password_field :password, autocomplete: "new-password" %>
<% if @minimum_password_length %>
<br />
<em><%= @minimum_password_length %> characters minimum</em>
<% end %>
</div>

<div class="field">
<%= f.label :password_confirmation %><br />
<%= f.password_field :password_confirmation, autocomplete: "new-password" %>
</div>

<div class="field">
<%= f.label :current_password %> <i>(we need your current password to confirm your changes)</i><br />
<%= f.password_field :current_password, autocomplete: "current-password" %>
</div>

<%= render "devise/shared/error_messages", resource: resource %>

<div class="actions">
<%= f.submit "Update" %>
</div>
<% end %>

<div class="cancel_back">
<div class="cancel_account">Unhappy?
<%= button_to "Cancel my account", registration_path(resource_name), data: { confirm: "Are you sure?", turbo_confirm: "Are you sure?" }, method: :delete %>
</div>

<%= link_to "Back", :back %>
</div>

</div>
Loading
Loading