Correção Segurança entrada PIN motorista QRcode
This commit is contained in:
BIN
Imagens para correção /Imagem colada (14).png
Normal file
BIN
Imagens para correção /Imagem colada (14).png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 53 KiB |
@@ -9,36 +9,53 @@ module Motorista
|
|||||||
layout 'application'
|
layout 'application'
|
||||||
|
|
||||||
# GET /motorista/login — tela com teclado de PIN
|
# GET /motorista/login — tela com teclado de PIN
|
||||||
def new; end
|
# Se veio de um QR Code, o motorista já está pré-identificado (só falta o PIN).
|
||||||
|
def new
|
||||||
|
@motorista_pre = User.motorista.ativos.find_by(id: session[:motorista_qr_id])
|
||||||
|
end
|
||||||
|
|
||||||
# POST /motorista/login — valida PIN
|
# POST /motorista/login — valida PIN
|
||||||
def create
|
def create
|
||||||
pin = params[:pin].to_s.strip
|
pin = params[:pin].to_s.strip
|
||||||
user = User.motorista.ativos.find_by(pin_code: pin)
|
user = User.motorista.ativos.find_by(pin_code: pin)
|
||||||
|
|
||||||
if pin.length == 4 && user
|
unless pin.length == 4 && user
|
||||||
|
@motorista_pre = User.motorista.ativos.find_by(id: session[:motorista_qr_id])
|
||||||
|
flash.now[:alert] = 'PIN não encontrado. Confira os 4 números e tente de novo.'
|
||||||
|
return render :new, status: :unprocessable_entity
|
||||||
|
end
|
||||||
|
|
||||||
|
# Segurança: se o login partiu de um QR Code, o PIN precisa ser do MESMO
|
||||||
|
# motorista do QR — impede usar o QR Code de outra pessoa.
|
||||||
|
qr_id = session[:motorista_qr_id]
|
||||||
|
if qr_id.present? && qr_id != user.id
|
||||||
|
@motorista_pre = User.motorista.ativos.find_by(id: qr_id)
|
||||||
|
flash.now[:alert] = 'Este PIN não corresponde ao QR Code lido. Use o seu PIN.'
|
||||||
|
return render :new, status: :unprocessable_entity
|
||||||
|
end
|
||||||
|
|
||||||
|
session.delete(:motorista_qr_id)
|
||||||
sign_in(user)
|
sign_in(user)
|
||||||
session[:mostrar_splash] = true
|
session[:mostrar_splash] = true
|
||||||
AuditoriaLog.registrar(user: user, acao: :login, entidade: 'User',
|
AuditoriaLog.registrar(user: user, acao: :login, entidade: 'User',
|
||||||
entidade_id: user.id, request: request)
|
entidade_id: user.id,
|
||||||
|
dados_novos: (qr_id.present? ? { via: 'qr_code+pin' } : nil),
|
||||||
|
request: request)
|
||||||
redirect_to motorista_dashboard_path, notice: "Bem-vindo, #{user.nome.split.first}!"
|
redirect_to motorista_dashboard_path, notice: "Bem-vindo, #{user.nome.split.first}!"
|
||||||
else
|
|
||||||
flash.now[:alert] = 'PIN não encontrado. Confira os 4 números e tente de novo.'
|
|
||||||
render :new, status: :unprocessable_entity
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# GET /motorista/acesso/:token — login via QR Code do holerite
|
# GET /motorista/acesso/:token — abre o login a partir do QR Code do holerite.
|
||||||
|
# SEGURANÇA: o QR apenas identifica o motorista; ele ainda precisa digitar o
|
||||||
|
# PIN de 4 dígitos para entrar (antes o QR logava direto, sem PIN).
|
||||||
def acesso_qr
|
def acesso_qr
|
||||||
user = User.motorista.ativos.find_by(login_token: params[:token])
|
user = User.motorista.ativos.find_by(login_token: params[:token])
|
||||||
|
|
||||||
if user
|
if user
|
||||||
sign_in(user)
|
session[:motorista_qr_id] = user.id
|
||||||
session[:mostrar_splash] = true
|
redirect_to motorista_login_path,
|
||||||
AuditoriaLog.registrar(user: user, acao: :login, entidade: 'User',
|
notice: "Olá, #{user.nome.split.first}! Digite seu PIN de 4 dígitos para entrar."
|
||||||
entidade_id: user.id, dados_novos: { via: 'qr_code' }, request: request)
|
|
||||||
redirect_to motorista_dashboard_path, notice: "Bem-vindo, #{user.nome.split.first}!"
|
|
||||||
else
|
else
|
||||||
|
session.delete(:motorista_qr_id)
|
||||||
redirect_to motorista_login_path, alert: 'QR Code inválido ou expirado. Entre com seu PIN.'
|
redirect_to motorista_login_path, alert: 'QR Code inválido ou expirado. Entre com seu PIN.'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -33,7 +33,7 @@
|
|||||||
<%# Card 1 — Valor Estimado (LARANJA) %>
|
<%# Card 1 — Valor Estimado (LARANJA) %>
|
||||||
<div class="bg-orange-500 rounded-2xl p-6">
|
<div class="bg-orange-500 rounded-2xl p-6">
|
||||||
<p class="text-black/80 font-bold uppercase tracking-wide">💰 Valor estimado deste mês</p>
|
<p class="text-black/80 font-bold uppercase tracking-wide">💰 Valor estimado deste mês</p>
|
||||||
<p class="text-black font-black text-5xl mt-2 leading-tight"><%= moeda(@valor_estimado) %></p>
|
<p class="text-black font-black text-4xl sm:text-5xl mt-2 leading-tight whitespace-nowrap"><%= moeda(@valor_estimado) %></p>
|
||||||
<p class="text-black/80 text-base mt-2">
|
<p class="text-black/80 text-base mt-2">
|
||||||
<%= @entregas_mes %> entregas feitas e confirmadas
|
<%= @entregas_mes %> entregas feitas e confirmadas
|
||||||
</p>
|
</p>
|
||||||
@@ -45,7 +45,7 @@
|
|||||||
<%# Card 2 — Valor Consolidado (BRANCO) %>
|
<%# Card 2 — Valor Consolidado (BRANCO) %>
|
||||||
<div class="bg-white rounded-2xl p-6">
|
<div class="bg-white rounded-2xl p-6">
|
||||||
<p class="text-gray-600 font-bold uppercase tracking-wide">✅ Valor fechado para pagamento</p>
|
<p class="text-gray-600 font-bold uppercase tracking-wide">✅ Valor fechado para pagamento</p>
|
||||||
<p class="text-black font-black text-5xl mt-2 leading-tight"><%= moeda(@valor_consolidado) %></p>
|
<p class="text-black font-black text-4xl sm:text-5xl mt-2 leading-tight whitespace-nowrap"><%= moeda(@valor_consolidado) %></p>
|
||||||
<p class="text-gray-600 text-base mt-2">
|
<p class="text-gray-600 text-base mt-2">
|
||||||
Soma dos pagamentos já confirmados pela empresa
|
Soma dos pagamentos já confirmados pela empresa
|
||||||
</p>
|
</p>
|
||||||
@@ -72,7 +72,7 @@
|
|||||||
<p class="text-gray-300 text-base mt-1">
|
<p class="text-gray-300 text-base mt-1">
|
||||||
📅 <%= l c.data_inicio, format: :short %> a <%= l c.data_fim, format: :short %>
|
📅 <%= l c.data_inicio, format: :short %> a <%= l c.data_fim, format: :short %>
|
||||||
</p>
|
</p>
|
||||||
<p class="text-orange-500 font-black text-3xl mt-1"><%= moeda(cm&.valor_total || 0) %></p>
|
<p class="text-orange-500 font-black text-3xl mt-1 whitespace-nowrap"><%= moeda(cm&.valor_total || 0) %></p>
|
||||||
<% if cm&.pago? %>
|
<% if cm&.pago? %>
|
||||||
<p class="text-green-400 text-sm mt-1">
|
<p class="text-green-400 text-sm mt-1">
|
||||||
💰 Pago em <%= l cm.pago_em.to_date, format: :short %>
|
💰 Pago em <%= l cm.pago_em.to_date, format: :short %>
|
||||||
|
|||||||
@@ -8,7 +8,12 @@
|
|||||||
<div class="text-center mb-8">
|
<div class="text-center mb-8">
|
||||||
<div class="w-16 h-16 bg-orange-500 rounded-2xl flex items-center justify-center font-black text-black text-3xl mx-auto mb-3">G</div>
|
<div class="w-16 h-16 bg-orange-500 rounded-2xl flex items-center justify-center font-black text-black text-3xl mx-auto mb-3">G</div>
|
||||||
<h1 class="text-white font-bold text-2xl">Reem Logística</h1>
|
<h1 class="text-white font-bold text-2xl">Reem Logística</h1>
|
||||||
|
<% if @motorista_pre %>
|
||||||
|
<p class="text-white text-lg mt-1">Olá, <span class="font-bold text-orange-400"><%= @motorista_pre.nome.split.first %></span>!</p>
|
||||||
|
<p class="text-gray-400 text-base">Confirme com seu PIN de 4 números</p>
|
||||||
|
<% else %>
|
||||||
<p class="text-gray-400 text-base mt-1">Digite seu PIN de 4 números</p>
|
<p class="text-gray-400 text-base mt-1">Digite seu PIN de 4 números</p>
|
||||||
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<%= form_with url: motorista_login_path, method: :post, id: 'form-pin' do |f| %>
|
<%= form_with url: motorista_login_path, method: :post, id: 'form-pin' do |f| %>
|
||||||
|
|||||||
Reference in New Issue
Block a user