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

Release - 0.2.0 #42

Merged
merged 43 commits into from Jun 21, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
5da306d
[#5] Edit default from email
malparty Jun 9, 2021
7175a1d
[#5] Add flash notice-alert in view layout
malparty Jun 9, 2021
50076a3
[#5] Generate basic User model from Devise
malparty Jun 9, 2021
10cbeea
[#5] Add firstname lastname to User
malparty Jun 9, 2021
b6ae354
[#5] Generate Devise views
malparty Jun 9, 2021
3b359ae
[#5] Add lastname and firstname to registration views
malparty Jun 9, 2021
3d8c6f4
[#293] Merge from setup-deploy branch to get empty view
malparty Jun 9, 2021
7147cf9
[#293] Add logout button
malparty Jun 9, 2021
c2c642b
[#293] Add before_action authenticate_user
malparty Jun 9, 2021
d656a8d
[#293] Setup DoorKeeper to embbed OAuth2
malparty Jun 9, 2021
38e6db8
[#293] Setup DoorKeeper to embbed OAuth2
malparty Jun 9, 2021
145411b
[#5] Hide sign out button when not logged
malparty Jun 10, 2021
b49d334
[#5] Edit default from email
malparty Jun 9, 2021
271ef92
[#5] Add flash notice-alert in view layout
malparty Jun 9, 2021
111bad2
[#5] Rebase from Config Deployment
malparty Jun 10, 2021
574b467
[#5] Add firstname lastname to User
malparty Jun 9, 2021
d150da1
[#5] Generate Devise views
malparty Jun 9, 2021
a57d6da
[#5] Add lastname and firstname to registration views
malparty Jun 9, 2021
3dbcb86
[#293] Add logout button
malparty Jun 9, 2021
bfe7091
[#293] Add before_action authenticate_user
malparty Jun 9, 2021
3131f03
[#293] Setup DoorKeeper to embbed OAuth2
malparty Jun 9, 2021
5fc126d
[#293] Setup DoorKeeper to embbed OAuth2
malparty Jun 9, 2021
f0a6257
[#5] Hide sign out button when not logged
malparty Jun 10, 2021
5d398cb
Merge branch 'feature/user-login-backend' of https://github.com/malpa…
malparty Jun 10, 2021
53ea9b7
[#5] Add user db seed for system tests
malparty Jun 10, 2021
e7389a9
[#5] Add login system tests
malparty Jun 10, 2021
7139952
root commit
malparty Jun 11, 2021
ad3fab5
[#5] Fix missing password_confirmation param in sign_up request
malparty Jun 11, 2021
49e917b
[#5] Add login and signup system tests
malparty Jun 11, 2021
557c936
[#5] Update system tests to use faster sign_in method helper
malparty Jun 14, 2021
d9a84e0
[#5] Add FFaker to fabricate users
malparty Jun 14, 2021
a52174d
[#5] Fix english mistakes in tests
malparty Jun 14, 2021
7f93b22
[#5] Remove duplicated email validation rule
malparty Jun 14, 2021
3408c30
[#5] Add missing line break in tests
malparty Jun 14, 2021
220792f
root commit
malparty Jun 11, 2021
4d46c2d
[#5] Remove module prefix I18n in views
malparty Jun 14, 2021
99a488b
[#5] Update email db type to citext
malparty Jun 14, 2021
3471a43
[#5] Rename lastname/firstname into last_name first_name
malparty Jun 14, 2021
76dd4ee
[#5] Fix missing renaming for lastname firstname
malparty Jun 14, 2021
2c92306
[#5] Fix spacing for clarity in authentication helper
malparty Jun 14, 2021
39f17ff
[#5] Merge email (citext) and renaming names into previous db migrations
malparty Jun 14, 2021
ff83bd7
[#5] Merge email (citext) and renaming names into previous db migrations
malparty Jun 14, 2021
ff6f012
Merge pull request #33 from malparty/feature/user-login-backend
malparty Jun 16, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions Gemfile
Expand Up @@ -17,6 +17,7 @@ gem 'i18n-js', '3.5.1' # A library to provide the I18n translations on the Javas
# Authentications & Authorizations
gem 'devise' # Authentication solution for Rails with Warden
gem 'pundit' # Minimal authorization through OO design and pure Ruby classes
gem 'doorkeeper' # Awesome OAuth 2 provider for your Rails / Grape app

# Assets
gem 'webpacker', '~>5.2.0' # Transpile app-like JavaScript
Expand Down Expand Up @@ -52,6 +53,7 @@ group :development, :test do
gem 'rubocop-rails', require: false # A RuboCop extension focused on enforcing Rails best practices and coding conventions.
gem 'rubocop-rspec', require: false # Code style checking for RSpec files
gem 'rubocop-performance', require: false # An extension of RuboCop focused on code performance checks.
gem 'ffaker' # used to easily generate fake data: names, addresses, phone numbers, etc.

gem 'undercover' # Report missing test coverage in new changes
gem 'danger' # Automated code review.
Expand Down
3 changes: 3 additions & 0 deletions Gemfile.lock
Expand Up @@ -157,6 +157,8 @@ GEM
warden (~> 1.2.3)
diff-lcs (1.4.4)
docile (1.4.0)
doorkeeper (5.5.1)
railties (>= 5)
erubi (1.10.0)
erubis (2.7.0)
fabrication (2.22.0)
Expand Down Expand Up @@ -480,6 +482,7 @@ DEPENDENCIES
danger-undercover
database_cleaner
devise
doorkeeper
fabrication
ffaker
figaro
Expand Down
16 changes: 16 additions & 0 deletions app/controllers/application_controller.rb
Expand Up @@ -2,4 +2,20 @@

class ApplicationController < ActionController::Base
include Localization

protect_from_forgery with: :exception

before_action :authenticate_user!
before_action :update_allowed_parameters, if: :devise_controller?

protected

def update_allowed_parameters
devise_parameter_sanitizer.permit(:sign_up) do |u|

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Has the variable name 'u'

u.permit(:first_name, :last_name, :email, :password, :password_confirmation)
end
devise_parameter_sanitizer.permit(:account_update) do |u|

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Has the variable name 'u'

u.permit(:first_name, :last_name, :email, :password, :current_password)
end
end
end
14 changes: 14 additions & 0 deletions app/models/user.rb
@@ -0,0 +1,14 @@
# frozen_string_literal: true

class User < ApplicationRecord
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :validatable

# the authenticate method from devise documentation
def self.authenticate(email, password)
user = User.find_for_authentication(email: email)
user&.valid_password?(password) ? user : nil

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Is controlled by argument 'password'

end
end
16 changes: 16 additions & 0 deletions app/views/devise/confirmations/new.html.erb
@@ -0,0 +1,16 @@
<h2>Resend confirmation instructions</h2>

<%= form_for(resource, as: resource_name, url: confirmation_path(resource_name), html: { method: :post }) do |f| %>
<%= render "devise/shared/error_messages", resource: resource %>

<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>

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

<%= render "devise/shared/links" %>
5 changes: 5 additions & 0 deletions app/views/devise/mailer/confirmation_instructions.html.erb
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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>
25 changes: 25 additions & 0 deletions app/views/devise/passwords/edit.html.erb
@@ -0,0 +1,25 @@
<h2>Change your password</h2>

<%= form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :put }) do |f| %>
<%= render "devise/shared/error_messages", resource: resource %>
<%= 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>

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

<%= render "devise/shared/links" %>
16 changes: 16 additions & 0 deletions app/views/devise/passwords/new.html.erb
@@ -0,0 +1,16 @@
<h2>Forgot your password?</h2>

<%= form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :post }) do |f| %>
<%= render "devise/shared/error_messages", resource: resource %>

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

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

<%= render "devise/shared/links" %>
53 changes: 53 additions & 0 deletions app/views/devise/registrations/edit.html.erb
@@ -0,0 +1,53 @@
<h2>Edit <%= resource_name.to_s.humanize %></h2>

<%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put }) do |f| %>
<%= render "devise/shared/error_messages", resource: resource %>

<div class="field">
<%= f.label :first_name %><br />
<%= f.text_field :first_name, autofocus: true %>
</div>

<div class="field">
<%= f.label :last_name %><br />
<%= f.text_field :last_name %>
</div>

<div class="field">
<%= f.label :email %><br />
<%= f.email_field :email, 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>

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

<h3>Cancel my account</h3>

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

<%= link_to "Back", :back %>
39 changes: 39 additions & 0 deletions app/views/devise/registrations/new.html.erb
@@ -0,0 +1,39 @@
<h2>Sign up</h2>

<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
<%= render "devise/shared/error_messages", resource: resource %>

<div class="field">
<%= f.label :first_name %><br />
<%= f.text_field :first_name, autofocus: true %>
</div>

<div class="field">
<%= f.label :last_name %><br />
<%= f.text_field :last_name %>
</div>

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

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

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

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

<%= render "devise/shared/links" %>
26 changes: 26 additions & 0 deletions app/views/devise/sessions/new.html.erb
@@ -0,0 +1,26 @@
<h2>Log in</h2>

<%= form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %>
<div class="field">
<%= f.label :email %><br />
<%= f.email_field :email, autofocus: true, autocomplete: "email" %>
</div>

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

<% if devise_mapping.rememberable? %>
<div class="field">
<%= f.check_box :remember_me %>
<%= f.label :remember_me %>
</div>
<% end %>

<div class="actions">
<%= f.submit "Log in" %>
</div>
<% end %>
<%= render "devise/shared/links" %>
15 changes: 15 additions & 0 deletions app/views/devise/shared/_error_messages.html.erb
@@ -0,0 +1,15 @@
<% if resource.errors.any? %>
<div id="error_explanation">
<h2>
<%= t("errors.messages.not_saved",
count: resource.errors.count,
resource: resource.class.model_name.human.downcase)
%>
</h2>
<ul>
<% resource.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
25 changes: 25 additions & 0 deletions app/views/devise/shared/_links.html.erb
@@ -0,0 +1,25 @@
<%- if controller_name != 'sessions' %>
<%= link_to "Log in", new_session_path(resource_name) %><br />
<% end %>

<%- if devise_mapping.registerable? && controller_name != 'registrations' %>
<%= link_to "Sign up", new_registration_path(resource_name) %><br />
<% end %>

<%- if devise_mapping.recoverable? && controller_name != 'passwords' && controller_name != 'registrations' %>
<%= link_to "Forgot your password?", new_password_path(resource_name) %><br />
<% end %>

<%- if devise_mapping.confirmable? && controller_name != 'confirmations' %>
<%= link_to "Didn't receive confirmation instructions?", new_confirmation_path(resource_name) %><br />
<% end %>

<%- if devise_mapping.lockable? && resource_class.unlock_strategy_enabled?(:email) && controller_name != 'unlocks' %>
<%= link_to "Didn't receive unlock instructions?", new_unlock_path(resource_name) %><br />
<% end %>

<%- if devise_mapping.omniauthable? %>
<%- resource_class.omniauth_providers.each do |provider| %>
<%= link_to "Sign in with #{OmniAuth::Utils.camelize(provider)}", omniauth_authorize_path(resource_name, provider), method: :post %><br />
<% end %>
<% end %>
16 changes: 16 additions & 0 deletions app/views/devise/unlocks/new.html.erb
@@ -0,0 +1,16 @@
<h2>Resend unlock instructions</h2>

<%= form_for(resource, as: resource_name, url: unlock_path(resource_name), html: { method: :post }) do |f| %>
<%= render "devise/shared/error_messages", resource: resource %>

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

<div class="actions">
<%= f.submit "Resend unlock instructions" %>
</div>
<% end %>
<%= render "devise/shared/links" %>
5 changes: 5 additions & 0 deletions app/views/layouts/application.html.erb
Expand Up @@ -11,6 +11,11 @@
</head>

<body>
<% if user_signed_in? %>
<%= button_to t('logout'), destroy_user_session_path, method: :delete %>
<% end %>
<p class="notice"><%= notice %></p>
<p class="alert"><%= alert %></p>
<%= yield %>
</body>
</html>
4 changes: 2 additions & 2 deletions config/initializers/devise.rb
Expand Up @@ -24,7 +24,7 @@
# Configure the e-mail address which will be shown in Devise::Mailer,
# note that it will be overwritten if you use your own mailer class
# with default "from" parameter.
config.mailer_sender = 'please-change-me-at-config-initializers-devise@example.com'
config.mailer_sender = 'noreply@nimblehq.co'

# Configure the class responsible to send e-mails.
# config.mailer = 'Devise::Mailer'
Expand Down Expand Up @@ -183,7 +183,7 @@
# Email regex used to validate email formats. It simply asserts that
# one (and only one) @ exists in the given string. This is mainly
# to give user feedback and not to assert the e-mail validity.
config.email_regexp = /\A[^@\s]+@[^@\s]+\z/
config.email_regexp = URI::MailTo::EMAIL_REGEXP

# ==> Configuration for :timeoutable
# The time you want to timeout the user session without activity. After this
Expand Down