diff --git a/app/controllers/v1/sessions_controller.rb b/app/controllers/v1/sessions_controller.rb index bbe5e9ecd2948f54da59f206600e3ed2632b01a7..ff474f08715b7056fd2a52bda37e79c159692f13 100644 --- a/app/controllers/v1/sessions_controller.rb +++ b/app/controllers/v1/sessions_controller.rb @@ -19,42 +19,71 @@ require 'open-uri' class V1::SessionsController < DeviseTokenAuth::SessionsController + + #function to create a new session def create - # Check - puts(resource_params) - field = (resource_params.keys.map(&:to_sym) & resource_class.authentication_keys).first + + #verify if the user exist and is active + if User.find_by_email(resource_params[:email]).present? + if User.find_by_email(resource_params[:email]).confirmed_at.present? + field = (resource_params.keys.map(&:to_sym) & resource_class.authentication_keys).first + @resource = nil - @resource = nil - if field - q_value = get_case_insensitive_field_from_resource_params(field) + if field + q_value = get_case_insensitive_field_from_resource_params(field) - @resource = find_resource(field, q_value) - end + @resource = find_resource(field, q_value) + end - if @resource && valid_params?(field, q_value) && (!@resource.respond_to?(:active_for_authentication?) || @resource.active_for_authentication?) - valid_password = @resource.valid_password?(resource_params[:password]) - if (@resource.respond_to?(:valid_for_authentication?) && !@resource.valid_for_authentication? { valid_password }) || !valid_password - return render_create_error_bad_credentials - end - @token = @resource.create_token - @resource.save + #verify the credentials + if @resource && valid_params?(field, q_value) && (!@resource.respond_to?(:active_for_authentication?) || @resource.active_for_authentication?) + valid_password = @resource.valid_password?(resource_params[:password]) + if (@resource.respond_to?(:valid_for_authentication?) && !@resource.valid_for_authentication? { valid_password }) || !valid_password + return render_create_error_bad_credentials + end + + @token = @resource.create_token + @resource.save - sign_in(:user, @resource, store: false, bypass: false) + sign_in(:user, @resource, store: false, bypass: false) - yield @resource if block_given? + yield @resource if block_given? - render_create_success - elsif @resource && !(!@resource.respond_to?(:active_for_authentication?) || @resource.active_for_authentication?) - # verify if user is to be reactivated - reactivate_user? - if @resource.blocked? - render_create_error_blocked - elsif @resource.banished? - render_create_error_banished + render_create_success + + elsif @resource && !(!@resource.respond_to?(:active_for_authentication?) || @resource.active_for_authentication?) + # verify if user is to be reactivated + reactivate_user? + if @resource.blocked? + render_create_error_blocked + elsif @resource.banished? + render_create_error_banished + end + + else + render_create_error_bad_credentials + end + + #in case of the user is not confirmed, find the user and send an email confirmation + else + @user = User.find_by_email(params[:email]) + UserMailer.email_confirmation(@user).deliver_now + return render_create_error_not_confirmed end - else - render_create_error_bad_credentials + + else + puts("Usuário não encontrado") + return render_create_error_bad_credentials end + + end + + def render_create_error_not_confirmed + render json: { + success: false, + errors: [ I18n.t("devise.failure.unconfirmed")], + }, status: 401 + end def render_create_error_banished diff --git a/app/controllers/v1/users_controller.rb b/app/controllers/v1/users_controller.rb index 138c45b5de824b2235d7544ca47c0c839174694c..6d187234d92a7695830e0fd8976d5821d85de28f 100644 --- a/app/controllers/v1/users_controller.rb +++ b/app/controllers/v1/users_controller.rb @@ -46,13 +46,20 @@ class V1::UsersController < ApplicationController render json: response, status: status end + def confirm_email + @user = User.find_by_confirm_token(params[:id]) + if @user + @user.email_activate + end + end + # POST /v1/users/purchase_item def purchase_item # purchases given item for current user item = Item.find_by(id: params[:item_id]) user_item = UserItem.where(user: current_user, item: item).first if !user_item.blank? - render json: { "error": "You already own this item." }, status: :unprocessable_entity + render json: { "error": "Você já possui este item." }, status: :unprocessable_entity else if current_user.points >= item.price - item.discount current_user.points -= item.price - item.discount @@ -63,7 +70,7 @@ class V1::UsersController < ApplicationController render json: current_user.user_items, status: :ok end else - render json: { "error": "You don't have the required points for this item." }, status: :unprocessable_entity + render json: { "error": "Você não possui gemas suficientes para esta compra." }, status: :unprocessable_entity end end end @@ -97,7 +104,7 @@ class V1::UsersController < ApplicationController # GET /v1/users/action_counters def action_counters - # retorna action_counters e contagens correspondentes + # return action_counters and counters for given user render json: paginate(current_user.action_counters), status: :ok end @@ -139,6 +146,7 @@ class V1::UsersController < ApplicationController authorize user if user.save + UserMailer.welcome_email(user).deliver_now render json: user, status: :created else render json: user.errors, status: :unprocessable_entity diff --git a/app/mailers/application_mailer.rb b/app/mailers/application_mailer.rb index 248a26994a93a14bafa79b6281ea82d335b71247..8f0e167ed6b1dafd0655a6054c1a6aea1c41a380 100644 --- a/app/mailers/application_mailer.rb +++ b/app/mailers/application_mailer.rb @@ -18,7 +18,7 @@ # along with portalmec. If not, see <http://www.gnu.org/licenses/>. class ApplicationMailer < ActionMailer::Base - default to: 'plataformaintegrada@mec.gov.br' + #default to: 'plataformaintegrada@mec.gov.br' default from: 'portalmec@inf.ufpr.br' - #layout 'mailer' + layout 'mailer' end diff --git a/app/mailers/email_mailer.rb b/app/mailers/email_mailer.rb deleted file mode 100644 index 31d8d5bf7972166fa0127edd16684314e0feee73..0000000000000000000000000000000000000000 --- a/app/mailers/email_mailer.rb +++ /dev/null @@ -1,27 +0,0 @@ - -# Copyright (C) 2015 Centro de Computacao Cientifica e Software Livre -# Departamento de Informatica - Universidade Federal do Parana -# -# This file is part of portalmec. -# -# portalmec is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# portalmec is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with portalmec. If not, see <http://www.gnu.org/licenses/>. - -class EmailMailer < ApplicationMailer - default from: 'integrada.contato@mec.gov.br' - - def new_email(email, to_address) - @email = email - mail(subject: @email.subject, to:to_address) - end -end diff --git a/app/mailers/user_mailer.rb b/app/mailers/user_mailer.rb new file mode 100644 index 0000000000000000000000000000000000000000..1bb6cc43c39f90705ba99b9470f0e97d15d1e210 --- /dev/null +++ b/app/mailers/user_mailer.rb @@ -0,0 +1,18 @@ +class UserMailer < ActionMailer::Base + + #set the default email sender + default from: 'portalmec_tec@inf.ufpr.br' + + #function to send email to user when he/she is created through the admin panel + def welcome_email (user) + @user = user + mail(to: @user.email, subject: 'Bem vindo ao PortalMec!') + end + + #function to send email confirmation to user, this view is located in app/views/user_mailer/email_confirmation.html.erb + def email_confirmation (user) + @user = user + mail(to: @user.email, subject: 'Confirmação de email') + end + +end diff --git a/app/models/user.rb b/app/models/user.rb index bc367036187c0f12c450b0bb23d779cd2fcfc0f0..aff98cd01b42fdbe4d2331abf82229f19260e029 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -88,7 +88,7 @@ class User < ApplicationRecord include Complainable include Publisher include Trackable - + # Include default devise modules. Others available are: # :confirmable, :lockable, :timeoutable and :omniauthable devise :database_authenticatable, :registerable, @@ -134,6 +134,8 @@ class User < ApplicationRecord has_many :action_counters has_many :actions, through: :action_counters + before_create :confirmation_token + after_create :default_role before_save :verify_teacher_id after_save :verify_dspace_info @@ -165,6 +167,13 @@ class User < ApplicationRecord # don't versionate frequently changed fields has_paper_trail ignore: [:tokens, :sign_in_count, :current_sign_in_at, :last_sign_in_at] + def email_activate + self.email_confirmed = true + self.confirm_token = nil + self.confirmed_at = Time.now.utc + save!(:validate => false) + end + def search_data { name: name, @@ -186,56 +195,72 @@ class User < ApplicationRecord def is_admin? roles.each do |role| - return true if role.name == 'admin' + if role.name == 'admin' + return true + end end false end def is_moderator? roles.each do |role| - return true if role.name == 'moderator' + if role.name == 'moderator' + return true + end end false end def is_curator? roles.each do |role| - return true if role.name == 'curator' + if role.name == 'curator' + return true + end end false end def is_supervisor? roles.each do |role| - return true if role.name == 'supervisor' + if role.name == 'supervisor' + return true + end end false end def is_editor? roles.each do |role| - return true if role.name == 'editor' + if role.name == 'editor' + return true + end end false end def is_submitter? roles.each do |role| - return true if role.name == 'submitter' + if role.name == 'submitter' + return true + end end false end def is_publisher? roles.each do |role| - return true if role.name == 'publisher' + if role.name == 'publisher' + return true + end end false end def is_partner? roles.each do |role| - return true if role.name == 'partner' + if role.name == 'partner' + return true + end end false end @@ -465,6 +490,13 @@ class User < ApplicationRecord roles << Role.submitter end + private + def confirmation_token + if self.confirm_token.blank? + self.confirm_token = SecureRandom.urlsafe_base64.to_s + end + end + def self.from_omniauth(access_token) user = User.find_by(email: user_email) return nil if user.blank? @@ -479,7 +511,7 @@ class User < ApplicationRecord password: Devise.friendly_token[0, 20] ) end - + def verify_dspace_info if roles.include?(Role.find_by_name("partner")) && !(changed & ["dspace_url", "dspace_handle", "dspace_sets"]).empty? DspaceMailer.dspace_info_updated(self).deliver_now diff --git a/app/views/layouts/mailer.text.erb b/app/views/layouts/mailer.text.erb new file mode 100644 index 0000000000000000000000000000000000000000..37f0bddbd746bc24923ce9a8eb0dae1ca3076284 --- /dev/null +++ b/app/views/layouts/mailer.text.erb @@ -0,0 +1 @@ +<%= yield %> diff --git a/app/views/user_mailer/email_confirmation.html.erb b/app/views/user_mailer/email_confirmation.html.erb new file mode 100644 index 0000000000000000000000000000000000000000..c2fa862dd64dcab4116f202e0c31da84e82416bd --- /dev/null +++ b/app/views/user_mailer/email_confirmation.html.erb @@ -0,0 +1,5 @@ +Olá, <%= @user.name %>, + +Seja bem vindo ao PortalMec, +Confirme seu email abaixo: +<%= confirm_email_v1_user_url(@user.confirm_token) %> \ No newline at end of file diff --git a/app/views/user_mailer/email_confirmation.text.erb b/app/views/user_mailer/email_confirmation.text.erb new file mode 100644 index 0000000000000000000000000000000000000000..2e5622583f8db032224060835dafcc3ef1042435 --- /dev/null +++ b/app/views/user_mailer/email_confirmation.text.erb @@ -0,0 +1 @@ +<%= confirm_email_v1_user_url(@user.confirm_token) %> \ No newline at end of file diff --git a/app/views/user_mailer/welcome_email.html.erb b/app/views/user_mailer/welcome_email.html.erb new file mode 100644 index 0000000000000000000000000000000000000000..8d106a84889980b41d1aa453f00e4ef0db2965a2 --- /dev/null +++ b/app/views/user_mailer/welcome_email.html.erb @@ -0,0 +1,13 @@ +<!DOCTYPE html> +<html> + <head> + <meta content='text/html; charset=UTF-8' http-equiv='Content-Type' /> + </head> + <body> + <h1>Bem vindo ao PortalMec!, <%= @user.name %> </h1> + <p> + Seu cadastro foi realizado com sucesso, agora você pode acessar o PortalMec. + </p> + <p>Obrigado!</p> + </body> +</html> diff --git a/app/views/user_mailer/welcome_email.text.erb b/app/views/user_mailer/welcome_email.text.erb new file mode 100644 index 0000000000000000000000000000000000000000..3daed056d1195fbc2bddcc7ec56b9fc336ad496f --- /dev/null +++ b/app/views/user_mailer/welcome_email.text.erb @@ -0,0 +1,6 @@ +Bem vindo ao PortalMec <%= @user.name %> ! +=============================================== + +Seu cadastro foi realizado com sucesso., + +Obrigado! \ No newline at end of file diff --git a/app/views/users/confirmations/new.html.erb b/app/views/users/confirmations/new.html.erb new file mode 100644 index 0000000000000000000000000000000000000000..4af186b288328a9af85b3ff88d16c4751516f048 --- /dev/null +++ b/app/views/users/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 "users/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 "users/shared/links" %> diff --git a/app/views/users/mailer/confirmation_instructions.html.erb b/app/views/users/mailer/confirmation_instructions.html.erb new file mode 100644 index 0000000000000000000000000000000000000000..dc55f64f69e2541d12e6ffd6e3f4a413e8b828b2 --- /dev/null +++ b/app/views/users/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> diff --git a/app/views/users/mailer/email_changed.html.erb b/app/views/users/mailer/email_changed.html.erb new file mode 100644 index 0000000000000000000000000000000000000000..32f4ba8038d81c16f86eab2262a761f56ef656c9 --- /dev/null +++ b/app/views/users/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 %> diff --git a/app/views/users/mailer/password_change.html.erb b/app/views/users/mailer/password_change.html.erb new file mode 100644 index 0000000000000000000000000000000000000000..b41daf476a35f81702a954445f624b98e15b54f1 --- /dev/null +++ b/app/views/users/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> diff --git a/app/views/users/mailer/reset_password_instructions.html.erb b/app/views/users/mailer/reset_password_instructions.html.erb new file mode 100644 index 0000000000000000000000000000000000000000..f667dc12fe34929983021920c39f4ca061c4fd4f --- /dev/null +++ b/app/views/users/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> diff --git a/app/views/users/mailer/unlock_instructions.html.erb b/app/views/users/mailer/unlock_instructions.html.erb new file mode 100644 index 0000000000000000000000000000000000000000..41e148bf2ac2d8b3f108e15c45f8a2e75fb0b07e --- /dev/null +++ b/app/views/users/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> diff --git a/app/views/users/passwords/edit.html.erb b/app/views/users/passwords/edit.html.erb new file mode 100644 index 0000000000000000000000000000000000000000..863ffbb223926b256b54195e0a8b58fe55f82598 --- /dev/null +++ b/app/views/users/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 "users/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 "users/shared/links" %> diff --git a/app/views/users/passwords/new.html.erb b/app/views/users/passwords/new.html.erb new file mode 100644 index 0000000000000000000000000000000000000000..3b30b06d611d54585f38afbfc9fc8c2ffe96545a --- /dev/null +++ b/app/views/users/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 "users/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 "users/shared/links" %> diff --git a/app/views/users/registrations/edit.html.erb b/app/views/users/registrations/edit.html.erb new file mode 100644 index 0000000000000000000000000000000000000000..038cd9459b5d483dd68f79e83011366b412623d3 --- /dev/null +++ b/app/views/users/registrations/edit.html.erb @@ -0,0 +1,43 @@ +<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 "users/shared/error_messages", resource: resource %> + + <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> + + <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 %> diff --git a/app/views/users/registrations/new.html.erb b/app/views/users/registrations/new.html.erb new file mode 100644 index 0000000000000000000000000000000000000000..61d1e4c7a3f24ccd8de063fb07f98f3b9ad65ed9 --- /dev/null +++ b/app/views/users/registrations/new.html.erb @@ -0,0 +1,29 @@ +<h2>Sign up</h2> + +<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %> + <%= render "users/shared/error_messages", resource: resource %> + + <div class="field"> + <%= f.label :email %><br /> + <%= f.email_field :email, autofocus: true, 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 "users/shared/links" %> diff --git a/app/views/users/sessions/new.html.erb b/app/views/users/sessions/new.html.erb new file mode 100644 index 0000000000000000000000000000000000000000..b892c8ac8dd7c245dc4ced158ef9947d30efdd11 --- /dev/null +++ b/app/views/users/sessions/new.html.erb @@ -0,0 +1,27 @@ +<div><%=notice%></div> +<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 "users/shared/links" %> diff --git a/app/views/users/shared/_error_messages.html.erb b/app/views/users/shared/_error_messages.html.erb new file mode 100644 index 0000000000000000000000000000000000000000..ba7ab887013255a06523bdee4d19189cb5b59b3c --- /dev/null +++ b/app/views/users/shared/_error_messages.html.erb @@ -0,0 +1,15 @@ +<% if resource.errors.any? %> + <div id="error_explanation"> + <h2> + <%= I18n.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 %> diff --git a/app/views/users/shared/_links.html.erb b/app/views/users/shared/_links.html.erb new file mode 100644 index 0000000000000000000000000000000000000000..96a9412417bf51257684ada2d9410c4e98e857ff --- /dev/null +++ b/app/views/users/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 %> diff --git a/app/views/users/unlocks/new.html.erb b/app/views/users/unlocks/new.html.erb new file mode 100644 index 0000000000000000000000000000000000000000..2f4fab8481b3687d2ee0892f63598e6ca590bb44 --- /dev/null +++ b/app/views/users/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 "users/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 "users/shared/links" %> diff --git a/config/environments/development.rb b/config/environments/development.rb index 692e9bd414be07a7850b10f578dd7ca728c1cbfb..8fb2c9be8979bb2e0ce7f5495980fdb80e5f0baf 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -99,7 +99,9 @@ Rails.application.configure do #config.action_mailer.default_url_options = { host: 'localhost', port: 3000 } # Lets define mailcatcher configs + + config.action_mailer.delivery_method = :smtp config.action_mailer.smtp_settings = { address: 'localhost', port: 1025 } - config.action_mailer.default_url_options = { host: 'localhost', port: 3000 } + config.action_mailer.default_url_options = { host: 'localhost', port: 3000 } end diff --git a/config/routes.rb b/config/routes.rb index d8d97c45cd6ecedd6a68d62fd1a1e209837a7f69..bc40d6920867908bfb49d5b915ef36968ccae62a 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -136,6 +136,12 @@ Rails.application.routes.draw do resources :actions resources :requirements + resources :users do + member do + get :confirm_email + end + end + resources :activities, only: [:index, :show] do collection do get 'me' @@ -172,7 +178,8 @@ Rails.application.routes.draw do get 'completed_achievements' end end - + + resources :reviews, only: :show # search routes diff --git a/db/migrate/20150731225848_devise_create_users.rb b/db/migrate/20150731225848_devise_create_users.rb index 3f42108dc8d9f7efc45e4ea38765db5ce4ec8402..9575cfd31fbd9f984abf42e1f5521c1947d69264 100644 --- a/db/migrate/20150731225848_devise_create_users.rb +++ b/db/migrate/20150731225848_devise_create_users.rb @@ -39,15 +39,15 @@ class DeviseCreateUsers < ActiveRecord::Migration[4.2] t.string :last_sign_in_ip ## Confirmable - # t.string :confirmation_token - # t.datetime :confirmed_at - # t.datetime :confirmation_sent_at - # t.string :unconfirmed_email # Only if using reconfirmable + #t.string :confirmation_token + #t.datetime :confirmed_at + #t.datetime :confirmation_sent_at + #t.string :unconfirmed_email # Only if using reconfirmable ## Lockable - # t.integer :failed_attempts, default: 0, null: false # Only if lock strategy is :failed_attempts - # t.string :unlock_token # Only if unlock strategy is :email or :both - # t.datetime :locked_at + t.integer :failed_attempts, default: 0, null: false # Only if lock strategy is :failed_attempts + t.string :unlock_token # Only if unlock strategy is :email or :both + t.datetime :locked_at t.timestamps null: false diff --git a/db/migrate/20220714142813_add_email_confirm_column_to_users.rb b/db/migrate/20220714142813_add_email_confirm_column_to_users.rb new file mode 100644 index 0000000000000000000000000000000000000000..c87dfb6c23464d1589fcb099cd228dfff31e913a --- /dev/null +++ b/db/migrate/20220714142813_add_email_confirm_column_to_users.rb @@ -0,0 +1,6 @@ +class AddEmailConfirmColumnToUsers < ActiveRecord::Migration[7.0] + def change + add_column :users, :email_confirmed, :boolean, :default => false + add_column :users, :confirm_token, :string + end +end diff --git a/spec/mailers/previews/user_preview.rb b/spec/mailers/previews/user_preview.rb new file mode 100644 index 0000000000000000000000000000000000000000..61f7cff238934b146ca2d40285eb29a8e442d002 --- /dev/null +++ b/spec/mailers/previews/user_preview.rb @@ -0,0 +1,4 @@ +# Preview all emails at http://localhost:3000/rails/mailers/user +class UserPreview < ActionMailer::Preview + +end diff --git a/spec/mailers/user_spec.rb b/spec/mailers/user_spec.rb new file mode 100644 index 0000000000000000000000000000000000000000..4a78b857a4acb52736297bb50d729b25a0612a42 --- /dev/null +++ b/spec/mailers/user_spec.rb @@ -0,0 +1,5 @@ +require "rails_helper" + +RSpec.describe UserMailer, type: :mailer do + pending "add some examples to (or delete) #{__FILE__}" +end