5
0
Fork 0
mirror of https://0xacab.org/sutty/sutty synced 2024-07-03 11:36:08 +00:00
panel/app/controllers/api/v1/invitades_controller.rb
f 22a7a811b4 Acomodar la API de formularios de contacto a los deploys nuevos.
La API no cambia por retrocompatibilidad pero ameritaría una v2 sabiendo
más cosas sobre CORS.
2021-08-08 22:23:03 -03:00

82 lines
2.6 KiB
Ruby

# frozen_string_literal: true
module Api
module V1
# Obtiene una cookie válida por el tiempo especificado por el
# sitio.
#
# Aunque visitemos el sitio varias veces enviando la cookie
# anterior, la cookie se renueva.
class InvitadesController < BaseController
# Cookie para el formulario de contacto
#
# Usamos where porque no nos importa encontrar el resultado, todes
# les visitantes reciben lo mismo, pero algunes no reciben cookie.
def contact_cookie
contact = Site.where(name: site_id, contact: true)
.pluck(:contact)
.first
set_cookie if contact
render file: Rails.root.join('public', '1x1.png'),
content_type: 'image/png',
layout: false
end
# Cookie para colaboraciones anónimas
def cookie
# XXX: Prestar atención a que estas acciones sean lo más rápidas
# y utilicen la menor cantidad posible de recursos, porque son
# un vector de DDOS.
anon = Site.where(name: site_id, colaboracion_anonima: true)
.pluck(:colaboracion_anonima)
.first
set_cookie if anon
render file: Rails.root.join('public', '1x1.png'),
content_type: 'image/png',
layout: false
end
private
# Genera el Origin correcto a partir de la URL del sitio.
#
# @see {https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin}
# @return [String]
def return_origin
site&.deploys&.find_by_hostname(origin_hostname)&.url
end
# La cookie no es accesible a través de JS y todo su contenido
# está cifrado para que no lo modifiquen les visitantes
#
# Enviamos un token de protección CSRF
def set_cookie
# TODO: Volver configurable por sitio
expires = ENV.fetch('COOKIE_DURATION', '30').to_i.minutes
# TODO: ¿Son necesarios estos headers en la descarga de una
# imagen? ¿No será mejor moverlos al envío de datos?
headers['Access-Control-Allow-Origin'] = return_origin
headers['Access-Control-Allow-Credentials'] = true
headers['Vary'] = 'Origin'
headers['Cache-Control'] = "private, max-age=#{expires}, stale-while-revalidate=#{expires}"
cookies.encrypted[site_id] = {
httponly: true,
secure: !Rails.env.test?,
expires: expires,
same_site: :strict,
value: {
csrf: form_authenticity_token,
expires: (Time.now + expires).to_i
}
}
end
end
end
end