Files
MatchLiveTv/backend/config/initializers/match_live_tv.rb
T
eminuxandCursor 79850dfc2c Non far crashare il reset password se SMTP rifiuta il destinatario.
Un account di test su dominio .test faceva 500; ora l'invio fallito viene loggato e l'API resta ok.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-31 12:00:22 +02:00

257 lines
6.8 KiB
Ruby
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
require "net/smtp"
require "openssl"
module MatchLiveTv
class << self
def jwt_secret
ENV.fetch("JWT_SECRET", Rails.application.secret_key_base)
end
def mediamtx_api_url
ENV.fetch("MEDIAMTX_API_URL", "http://localhost:9997")
end
def mediamtx_rtmp_url
ENV.fetch("MEDIAMTX_RTMP_URL", "rtmp://localhost:1935")
end
def mediamtx_webhook_secret
ENV.fetch("MEDIAMTX_WEBHOOK_SECRET", "change_me")
end
def reconnect_timeout_seconds
ENV.fetch("RECONNECT_TIMEOUT_SECONDS", "300").to_i
end
def hls_public_url
ENV.fetch("HLS_PUBLIC_URL") { "#{app_public_url.chomp('/')}/hls" }
end
def mediamtx_hls_url
ENV.fetch("MEDIAMTX_HLS_URL", "http://mediamtx:8888")
end
def app_public_url
ENV.fetch("APP_PUBLIC_URL", "http://localhost:3000")
end
def stripe_secret_key
ENV["STRIPE_SECRET_KEY"].presence
end
def stripe_webhook_secret
ENV["STRIPE_WEBHOOK_SECRET"].presence
end
def stripe_premium_light_yearly_price_id
ENV["STRIPE_PREMIUM_LIGHT_YEARLY_PRICE_ID"].presence ||
ENV["STRIPE_PREMIUM_LIGHT_PRICE_ID"].presence ||
ENV["STRIPE_PREMIUM_PRICE_ID"].presence
end
def stripe_premium_light_monthly_price_id
ENV["STRIPE_PREMIUM_LIGHT_MONTHLY_PRICE_ID"].presence
end
def stripe_premium_full_yearly_price_id
ENV["STRIPE_PREMIUM_FULL_YEARLY_PRICE_ID"].presence ||
ENV["STRIPE_PREMIUM_FULL_PRICE_ID"].presence ||
ENV["STRIPE_PREMIUM_PRICE_ID"].presence
end
def stripe_premium_full_monthly_price_id
ENV["STRIPE_PREMIUM_FULL_MONTHLY_PRICE_ID"].presence
end
# Retrocompatibilità
def stripe_premium_light_price_id
stripe_premium_light_yearly_price_id.to_s
end
def stripe_premium_full_price_id
stripe_premium_full_yearly_price_id.to_s
end
def stripe_enabled?
stripe_secret_key.present?
end
def bank_transfer_iban
ENV["BANK_TRANSFER_IBAN"].to_s.gsub(/\s+/, "").presence
end
def bank_transfer_account_holder
ENV["BANK_TRANSFER_ACCOUNT_HOLDER"].to_s.strip.presence
end
def bank_transfer_bank_name
ENV["BANK_TRANSFER_BANK_NAME"].to_s.strip.presence
end
def bank_transfer_bic
ENV["BANK_TRANSFER_BIC"].to_s.strip.presence
end
def bank_transfer_proof_email
ENV["BANK_TRANSFER_PROOF_EMAIL"].presence || support_email
end
def bank_transfer_configured?
bank_transfer_iban.present? && bank_transfer_account_holder.present?
end
def smtp_configured?
ENV["SMTP_ADDRESS"].present?
end
# In produzione senza SMTP non blocca il flusso (es. collaudo): la mail si può inviare a mano.
# Errori SMTP (dominio invalido, EOF Aruba, porta chiusa) non devono far crashare la request.
def deliver_mail(mail)
if Rails.env.production? && !smtp_configured?
Rails.logger.info("[mail] skip (SMTP assente): #{mail.subject}")
return false
end
mail.deliver_now
true
rescue EOFError, Net::SMTPError, Errno::ECONNREFUSED, Errno::ETIMEDOUT, SocketError, OpenSSL::SSL::SSLError => e
Rails.logger.warn("[mail] delivery failed: #{mail.subject} #{e.class}: #{e.message}")
false
end
def privacy_controller_name
ENV.fetch("PRIVACY_CONTROLLER_NAME", "Emiliano Frascaro")
end
def privacy_controller_email
ENV.fetch("PRIVACY_CONTACT_EMAIL", "privacy@matchlivetv.it")
end
# Email di supporto (App Store Support URL e contatti assistenza).
# Preferisce SUPPORT_CONTACT_EMAIL; default = contatto commerciale già usato nel sito.
def support_email
ENV["SUPPORT_CONTACT_EMAIL"].presence || "info@matchlivetv.it"
end
def privacy_controller_address
ENV.fetch("PRIVACY_CONTROLLER_ADDRESS", "Via Guido De Ruggiero, 89 - 20142 - Milano (MI)")
end
def privacy_controller_vat
ENV["PRIVACY_CONTROLLER_VAT"].presence
end
def mail_from
ENV.fetch("MAILER_FROM", "Match Live TV <noreply@matchlivetv.it>")
end
def password_reset_expiry_hours
ENV.fetch("PASSWORD_RESET_EXPIRY_HOURS", "2").to_i
end
def replay_storage_configured?
replay_storage_endpoint.present? || replay_storage_local?
end
def replay_storage_endpoint
ENV["REPLAY_STORAGE_ENDPOINT"].presence
end
def replay_storage_bucket
ENV.fetch("REPLAY_STORAGE_BUCKET", "matchlivetv-replays")
end
def replay_storage_region
ENV.fetch("REPLAY_STORAGE_REGION", "garage")
end
def replay_storage_access_key_id
ENV["REPLAY_STORAGE_ACCESS_KEY_ID"].presence
end
def replay_storage_secret_access_key
ENV["REPLAY_STORAGE_SECRET_ACCESS_KEY"].presence
end
def replay_storage_force_path_style?
ENV.fetch("REPLAY_STORAGE_FORCE_PATH_STYLE", "true") == "true"
end
def replay_storage_local?
replay_storage_endpoint.blank?
end
def recordings_local_path
ENV.fetch("RECORDINGS_PATH", "/recordings")
end
def replay_presigned_url_ttl_seconds
ENV.fetch("REPLAY_PRESIGNED_URL_TTL_SECONDS", "7200").to_i
end
def replay_download_url_ttl_seconds
ENV.fetch("REPLAY_DOWNLOAD_URL_TTL_SECONDS", "900").to_i
end
def replay_media_public_base_url
ENV.fetch("REPLAY_MEDIA_PUBLIC_BASE_URL") { "#{app_public_url.chomp('/')}/media" }
end
def replay_media_redirect_enabled?
return false if replay_storage_local?
ENV.fetch("REPLAY_MEDIA_REDIRECT", "true") == "true"
end
# Retention copia temporanea post-live YouTube (ore). Clamp 2472, default 48.
def youtube_temp_replay_retention_hours
raw = ENV.fetch("YOUTUBE_TEMP_REPLAY_RETENTION_HOURS", "48").to_i
raw.clamp(24, 72)
end
def youtube_replay_verify_max_attempts
ENV.fetch("YOUTUBE_REPLAY_VERIFY_MAX_ATTEMPTS", "12").to_i
end
def youtube_replay_verify_base_interval_secs
ENV.fetch("YOUTUBE_REPLAY_VERIFY_BASE_INTERVAL_SECS", "300").to_i
end
def youtube_replay_verify_grace_secs
ENV.fetch("YOUTUBE_REPLAY_VERIFY_GRACE_SECS", "120").to_i
end
def ops_http_rails_url
ENV.fetch("OPS_HTTP_RAILS_URL", "http://edge/up")
end
def ops_http_public_interval_seconds
ENV.fetch("OPS_HTTP_PUBLIC_INTERVAL_SECS", "900").to_i
end
def ops_up_latency_warn_ms
ENV.fetch("OPS_UP_LATENCY_WARN_MS", "2000").to_i
end
def ops_up_latency_crit_ms
ENV.fetch("OPS_UP_LATENCY_CRIT_MS", "5000").to_i
end
def google_analytics_measurement_id
ENV["GOOGLE_ANALYTICS_MEASUREMENT_ID"].presence
end
def google_analytics_configured?
google_analytics_measurement_id.present?
end
def app_store_url
"https://apps.apple.com/us/app/matchlivetv/id6799510705"
end
def play_store_url
"https://play.google.com/store/apps/details?id=com.matchlivetv.match_live_tv"
end
end
end