Skip to content

Commit

Permalink
Merge pull request #7 from Microverse-Fullstack-Program/authentication
Browse files Browse the repository at this point in the history
[Blog app] Milestone 7 - Authentication with Devise
  • Loading branch information
cherelemma authored Jul 13, 2023
2 parents ca11c88 + 58f0985 commit 3f8c24f
Show file tree
Hide file tree
Showing 30 changed files with 913 additions and 9 deletions.
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

0 comments on commit 3f8c24f

Please sign in to comment.