Adição da função de configuração de email e whatts

This commit is contained in:
2026-08-11 13:31:22 -03:00
parent e8f470f878
commit e530815377
27 changed files with 1461 additions and 92 deletions

View File

@@ -0,0 +1,71 @@
# app/models/concerns/atributo_cifrado.rb
#
# Cifra atributos sensíveis (senha SMTP, token do Twilio) em colunas
# `<nome>_cifrado` usando ActiveSupport::MessageEncryptor (AES-256-GCM).
#
# POR QUE NÃO ActiveRecord Encryption (`encrypts :campo`): este projeto não usa
# `config/credentials.yml.enc` nem `config/master.key` — tudo vem do .env. Ligar
# o AR Encryption exigiria configurar 3 chaves novas e depender da ordem de
# execução dos initializers do framework. Aqui a chave é DERIVADA do
# secret_key_base, sem nada novo para o operador gerar.
#
# ⚠️ ROTAÇÃO: se o SECRET_KEY_BASE do servidor for trocado, os valores já
# gravados viram ilegíveis. O reader devolve nil (nunca estoura 500), o app
# cai no fallback do .env e a tela mostra um aviso pedindo para redigitar.
# Para ficar imune a isso, defina NOTIFICACAO_SECRET no .env (qualquer string
# longa e fixa) — a derivação passa a usar ela em vez do secret_key_base.
module AtributoCifrado
extend ActiveSupport::Concern
SALT = 'reem-notas/notificacao/v1'
class_methods do
def atributo_cifrado(*nomes)
nomes.each do |nome|
coluna = :"#{nome}_cifrado"
define_method(nome) { AtributoCifrado.decifrar(self[coluna]) }
define_method(:"#{nome}=") do |valor|
texto = valor.to_s
# Sem isso, salvar a tela sem mexer no campo geraria um criptograma
# novo (o IV é aleatório) e o dirty tracking acusaria mudança à toa.
next if texto == send(nome)
self[coluna] = texto.blank? ? nil : AtributoCifrado.cifrar(texto)
end
define_method(:"#{nome}?") { send(nome).present? }
end
end
end
def self.cifrar(texto)
cofre.encrypt_and_sign(texto)
end
def self.decifrar(blob)
return nil if blob.blank?
cofre.decrypt_and_verify(blob)
rescue ActiveSupport::MessageEncryptor::InvalidMessage,
ActiveSupport::MessageVerifier::InvalidSignature => e
Rails.logger.error("[AtributoCifrado] valor ilegível (SECRET_KEY_BASE mudou?): #{e.class}")
nil
end
# O default do MessageEncryptor no Rails 7.1 é aes-256-gcm → chave de 32 bytes.
def self.cofre
@cofre ||= ActiveSupport::MessageEncryptor.new(chave)
end
def self.chave
if (segredo = ENV['NOTIFICACAO_SECRET'].presence)
ActiveSupport::KeyGenerator
.new(segredo, hash_digest_class: OpenSSL::Digest::SHA256)
.generate_key(SALT, 32)
else
Rails.application.key_generator.generate_key(SALT, 32)
end
end
end