Amélioration de présentation des formulaires de session…

This commit is contained in:
Jérémy Lecour 2022-01-26 18:43:30 +01:00 committed by Jérémy Lecour
parent 506f311573
commit aaff875024
15 changed files with 307 additions and 62 deletions

View file

@ -1,4 +1,6 @@
class AccountsController < ApplicationController
layout "anonymous", except: [:edit, :destroy, :update]
before_action :authenticate_user!, only: [:edit, :destroy, :update]
before_action :redirect_if_authenticated, only: [:create, :new]

View file

@ -0,0 +1,28 @@
class Api::V1::ApiKeysController < Api::V1::BaseController
# Require API key authentication
prepend_before_action :authenticate_with_api_key!, only: %i[index destroy]
def index
render json: current_bearer.api_keys
end
def create
authenticate_with_http_basic do |email, password|
user = User.find_by email: email
if user&.authenticate(password)
api_key = user.api_keys.create! token: SecureRandom.hex
render json: api_key, status: :created and return
end
end
render status: :unauthorized
end
def destroy
api_key = current_bearer.api_keys.find(params[:id])
api_key.destroy
end
end

View file

@ -30,7 +30,7 @@ module BasicAuthentication
end
def redirect_if_authenticated
redirect_to root_path, alert: "You are already logged in." if user_signed_in?
redirect_to checks_path, alert: "You are already logged in." if user_signed_in?
end
def remember(user)

View file

@ -1,4 +1,5 @@
class ConfirmationsController < ApplicationController
layout "anonymous"
def create
@user = User.find_by(email: params[:user][:email].downcase)

View file

@ -1,4 +1,6 @@
class PasswordsController < ApplicationController
layout "anonymous"
before_action :redirect_if_authenticated
def create

View file

@ -1,4 +1,6 @@
class SessionsController < ApplicationController
layout "anonymous"
before_action :redirect_if_authenticated, only: [:create, :new]
before_action :authenticate_user!, only: [:destroy]

View file

@ -1,20 +1,57 @@
<%= form_with model: @user, url: sign_up_path do |form| %>
<%= render partial: "shared/form_errors", locals: { object: form.object } %>
<div>
<%= form.label :email %>
<%= form.text_field :email, required: true, autofocus: true, autocomplete: "email" %>
<div class="min-h-full flex flex-col justify-center py-12 sm:px-6 lg:px-8">
<div class="sm:mx-auto sm:w-full sm:max-w-md">
<h2 class="text-center text-3xl font-extrabold text-gray-900">
Sign up for an account
</h2>
<p class="mt-2 text-center text-sm text-gray-600">
Or
<%= link_to "sign in to your account", login_path, class: "font-medium text-indigo-600 hover:text-indigo-500" %>
</p>
</div>
<div>
<%= form.label :name %>
<%= form.text_field :name, autocomplete: "name" %>
<div class="mt-8 sm:mx-auto sm:w-full sm:max-w-md">
<div class="bg-white py-8 px-4 shadow sm:rounded-lg sm:px-10">
<%= form_with model: @user, url: sign_up_path, class: "space-y-6" do |form| %>
<%= render partial: "shared/form_errors", locals: { object: form.object } %>
<div>
<%= form.label :email, class: "block text-sm font-medium text-gray-700" do %>
Email address
<% end %>
<div class="mt-1">
<%= form.text_field :email, required: true, autofocus: true, autocomplete: "email", class: "appearance-none block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm placeholder-gray-400 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" %>
</div>
</div>
<div>
<%= form.label :name, class: "block text-sm font-medium text-gray-700" do %>
Your name
<% end %>
<div class="mt-1">
<%= form.text_field :name, autocomplete: "name", class: "appearance-none block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm placeholder-gray-400 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" %>
</div>
</div>
<div>
<%= form.label :password, class: "block text-sm font-medium text-gray-700" do %>
Password
<% end %>
<div class="mt-1">
<%= form.password_field :password, required: true, autocomplete: "new-password", class: "appearance-none block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm placeholder-gray-400 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" %>
</div>
</div>
<div>
<%= form.label :password_confirmation, class: "block text-sm font-medium text-gray-700" do %>
Password confirmation
<% end %>
<div class="mt-1">
<%= form.password_field :password_confirmation, required: true, autocomplete: "new-password", class: "appearance-none block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm placeholder-gray-400 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" %>
</div>
</div>
<div>
<%= form.submit "Sign Up", class: "w-full flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500" %>
</div>
<% end %>
</div>
</div>
<div>
<%= form.label :password %>
<%= form.password_field :password, required: true, autocomplete: "new-password" %>
</div>
<div>
<%= form.label :password_confirmation %>
<%= form.password_field :password_confirmation, required: true, autocomplete: "new-password" %>
</div>
<%= form.submit "Sign Up" %>
<% end %>
</div>

View file

@ -2,7 +2,6 @@
<div class="flex justify-between items-center">
<h1 class="font-bold text-4xl">Checks</h1>
<%= link_to 'New check', new_check_path, class: "rounded-lg py-3 px-5 bg-blue-600 text-white block font-medium" %>
</div>
<div id="checks" class="min-w-full px-4 py-8 sm:px-0">
@ -23,7 +22,7 @@
Description
</th>
<th scope="col" class="relative px-6 py-3">
<span class="sr-only">Edit</span>
<span class="sr-only">Actions</span>
</th>
</tr>
</thead>
@ -41,7 +40,6 @@
</td>
<td class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
<%= link_to "Show", check, class: "text-indigo-600 hover:text-indigo-900" %>
<%= link_to 'Edit', edit_check_path(check), class: "text-indigo-600 hover:text-indigo-900" %>
</td>
</tr>
<% end %>

View file

@ -1,4 +1,30 @@
<%= form_with model: @user, url: confirmations_path do |form| %>
<%= form.email_field :email, required: true %>
<%= form.submit "Confirm Email" %>
<% end %>
<div class="min-h-full flex flex-col justify-center py-12 sm:px-6 lg:px-8">
<div class="sm:mx-auto sm:w-full sm:max-w-md">
<h2 class="text-center text-3xl font-extrabold text-gray-900">
Resend instructions
</h2>
<p class="mt-2 text-center text-sm text-gray-600">
Or
<%= link_to "back to sign-in", login_path, class: "font-medium text-indigo-600 hover:text-indigo-500" %>
</p>
</div>
<div class="mt-8 sm:mx-auto sm:w-full sm:max-w-md">
<div class="bg-white py-8 px-4 shadow sm:rounded-lg sm:px-10">
<%= form_with model: @user, url: confirmations_path, class: "space-y-6" do |form| %>
<div>
<%= form.label :email, class: "block text-sm font-medium text-gray-700" do %>
Email address
<% end %>
<div class="mt-1">
<%= form.text_field :email, required: true, autocomplete: "email", class: "appearance-none block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm placeholder-gray-400 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" %>
</div>
</div>
<div>
<%= form.submit "Confirm Email", class: "w-full flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500" %>
</div>
<% end %>
</div>
</div>
</div>

View file

@ -0,0 +1,73 @@
<!DOCTYPE html>
<html class="h-full bg-gray-100">
<head>
<title>Evocheck</title>
<meta name="viewport" content="width=device-width,initial-scale=1">
<%= csrf_meta_tags %>
<%= csp_meta_tag %>
<%= stylesheet_link_tag "tailwind", "inter-font", "data-turbo-track": "reload" %>
<%= stylesheet_link_tag "application", "data-turbo-track": "reload" %>
<%= javascript_importmap_tags %>
</head>
<body class="h-full">
<div class="min-h-full">
<div class="py-10">
<main>
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
<% if notice.present? %>
<!-- This example requires Tailwind CSS v2.0+ -->
<div class="rounded-md bg-yellow-50 p-4" data-controller="notification" data-notification-target="notificationWrapper">
<div class="flex">
<div class="flex-shrink-0">
<%= heroicon "check-circle", variant: :solid, options: { class: "h-5 w-5 text-yellow-400" } %>
</div>
<div class="ml-3">
<p class="text-sm font-medium text-yellow-800">
<%= notice %>
</p>
</div>
<div class="ml-auto pl-3">
<div class="-mx-1.5 -my-1.5">
<button type="button" class="inline-flex bg-yellow-50 rounded-md p-1.5 text-yellow-500 hover:bg-yellow-100 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-yellow-50 focus:ring-yellow-600" data-action="click->notification#dismiss">
<span class="sr-only">Dismiss</span>
<%= heroicon "x", variant: :solid, options: { class: "h-5 w-5" } %>
</button>
</div>
</div>
</div>
</div>
<% end %>
<% if alert.present? %>
<!-- This example requires Tailwind CSS v2.0+ -->
<div class="rounded-md bg-red-50 p-4" data-controller="notification" data-notification-target="notificationWrapper">
<div class="flex">
<div class="flex-shrink-0">
<%= heroicon "check-circle", variant: :solid, options: { class: "h-5 w-5 text-red-400" } %>
</div>
<div class="ml-3">
<p class="text-sm font-medium text-red-800">
<%= alert %>
</p>
</div>
<div class="ml-auto pl-3">
<div class="-mx-1.5 -my-1.5">
<button type="button" class="inline-flex bg-red-50 rounded-md p-1.5 text-red-500 hover:bg-red-100 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-red-50 focus:ring-red-600" data-action="click->notification#dismiss">
<span class="sr-only">Dismiss</span>
<%= heroicon "x", variant: :solid, options: { class: "h-5 w-5" } %>
</button>
</div>
</div>
</div>
</div>
<% end %>
<%= yield %>
</div>
</main>
</div>
</div>
</body>
</html>

View file

@ -1,4 +1,30 @@
<%= form_with url: passwords_path, scope: :user do |form| %>
<%= form.email_field :email, required: true %>
<%= form.submit "Reset Password" %>
<% end %>
<div class="min-h-full flex flex-col justify-center py-12 sm:px-6 lg:px-8">
<div class="sm:mx-auto sm:w-full sm:max-w-md">
<h2 class="text-center text-3xl font-extrabold text-gray-900">
Forgot your password?
</h2>
<p class="mt-2 text-center text-sm text-gray-600">
Or
<%= link_to "back to sign-in", login_path, class: "font-medium text-indigo-600 hover:text-indigo-500" %>
</p>
</div>
<div class="mt-8 sm:mx-auto sm:w-full sm:max-w-md">
<div class="bg-white py-8 px-4 shadow sm:rounded-lg sm:px-10">
<%= form_with url: passwords_path, scope: :user, class: "space-y-6" do |form| %>
<div>
<%= form.label :email, class: "block text-sm font-medium text-gray-700" do %>
Email address
<% end %>
<div class="mt-1">
<%= form.text_field :email, required: true, autocomplete: "email", class: "appearance-none block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm placeholder-gray-400 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" %>
</div>
</div>
<div>
<%= form.submit "Reset Password", class: "w-full flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500" %>
</div>
<% end %>
</div>
</div>
</div>

View file

@ -1,15 +1,70 @@
<%= form_with url: login_path, scope: :user do |form| %>
<div>
<%= form.label :email %>
<%= form.text_field :email, required: true %>
<div class="min-h-full flex flex-col justify-center py-12 sm:px-6 lg:px-8">
<div class="sm:mx-auto sm:w-full sm:max-w-md">
<h2 class="text-center text-3xl font-extrabold text-gray-900">
Sign in to your account
</h2>
<p class="mt-2 text-center text-sm text-gray-600">
Or
<%= link_to "sign up for an account", sign_up_path, class: "font-medium text-indigo-600 hover:text-indigo-500" %>
</p>
</div>
<div>
<%= form.label :password %>
<%= form.password_field :password, required: true %>
<div class="mt-8 sm:mx-auto sm:w-full sm:max-w-md">
<div class="bg-white py-8 px-4 shadow sm:rounded-lg sm:px-10">
<%= form_with url: login_path, scope: :user, class: "space-y-6" do |form| %>
<div>
<%= form.label :email, class: "block text-sm font-medium text-gray-700" do %>
Email address
<% end %>
<div class="mt-1">
<%= form.text_field :email, required: true, autocomplete: "email", class: "appearance-none block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm placeholder-gray-400 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" %>
</div>
</div>
<div>
<%= form.label :password, class: "block text-sm font-medium text-gray-700" do %>
Password
<% end %>
<div class="mt-1">
<%= form.password_field :password, required: true, autocomplete: "password", class: "appearance-none block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm placeholder-gray-400 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" %>
</div>
</div>
<div class="flex items-center justify-between">
<div class="flex items-center">
<%= form.check_box :remember_me, class: "h-4 w-4 text-indigo-600 focus:ring-indigo-500 border-gray-300 rounded" %>
<%= form.label :remember_me, class: "ml-2 block text-sm text-gray-900" do %>
Remember me
<% end %>
</div>
</div>
<div>
<%= form.submit "Sign In", class: "w-full flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500" %>
</div>
<% end %>
<div class="mt-6">
<div class="relative">
<div class="absolute inset-0 flex items-center">
<div class="w-full border-t border-gray-300"></div>
</div>
<div class="relative flex justify-center text-sm">
<span class="px-2 bg-white text-gray-500">
Something wrong?
</span>
</div>
</div>
<div>
<div class="mt-2 text-sm">
<%= link_to "I forgot my password!", new_password_path, class: "font-medium text-indigo-600 hover:text-indigo-500" %>
</div>
<div class="mt-2 text-sm">
<%= link_to "I didn't receive confirmation instructions!", new_confirmation_path, class: "font-medium text-indigo-600 hover:text-indigo-500" %>
</div>
</div>
</div>
</div>
</div>
<div>
<%= form.label :remember_me %>
<%= form.check_box :remember_me %>
</div>
<%= form.submit "Sign In" %>
<% end %>
</div>

View file

@ -1,5 +1,2 @@
<%= link_to "Your Profile", account_path, class: common_classes + " " + active_classes %>
<%= link_to "Settings", "#", class: common_classes + " " + active_classes %>
<div data-turbo="false">
<%= button_to "Sign out", logout_path, method: :delete, class: common_classes + " " + active_classes + " inline" %>
</div>
<%= link_to "Your Profile", account_path, class: common_classes + " " + active_classes %>
<%= button_to "Sign out", logout_path, method: :delete, class: common_classes + " " + active_classes + " text-left w-full", data: { 'turbo-confirm': "Are you sure?" } %>

View file

@ -1,14 +1,12 @@
<h1>Rails Authentication From Scratch</h1>
<ul>
<% if user_signed_in? %>
<li><%= link_to "My Acount", account_path %></li>
<li><%= button_to "Logout", logout_path, method: :delete %></li>
<% else %>
<li><%= link_to "Login", login_path %></li>
<li><%= link_to "Sign Up", sign_up_path %></li>
<li><%= link_to "Forgot my password", new_password_path %></li>
<li><%= link_to "Didn't receive confirmation instructions", new_confirmation_path %></li>
<% end %>
</ul>
<ul>
<% if user_signed_in? %>
<li><%= link_to "My Acount", account_path %></li>
<li><%= button_to "Logout", logout_path, method: :delete %></li>
<% else %>
<li><%= link_to "Login", login_path %></li>
<li><%= link_to "Sign Up", sign_up_path %></li>
<li><%= link_to "Forgot my password", new_password_path %></li>
<li><%= link_to "Didn't receive confirmation instructions", new_confirmation_path %></li>
<% end %>
</ul>

View file

@ -10,7 +10,7 @@ Rails.application.routes.draw do
end
# Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html
root "static_pages#home"
root "sessions#new"
post "sign_up", to: "accounts#create"
get "sign_up", to: "accounts#new"