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.
This commit is contained in:
parent
61b3b97313
commit
22a7a811b4
5 changed files with 56 additions and 14 deletions
|
@ -21,7 +21,22 @@ module Api
|
|||
# TODO: Generar API v2 que use solo el hostname y no haya que
|
||||
# pasar site_id como parámetro redundante.
|
||||
def site_id
|
||||
@site_id ||= Deploy.where(hostname: params[:site_id]).pluck(:site_id).first
|
||||
@site_id ||= Deploy.site_name_from_hostname(params[:site_id])
|
||||
end
|
||||
|
||||
# @return [Site]
|
||||
def site
|
||||
@site ||= Site.find_by_name(site_id)
|
||||
end
|
||||
|
||||
# Obtiene el hostname desde el Origin, con el hostname local como
|
||||
# fallback.
|
||||
#
|
||||
# @return [String]
|
||||
def origin_hostname
|
||||
URI.parse(origin || origin_from_referer).host
|
||||
rescue StandardError
|
||||
"#{site_id}.#{Site.domain}"
|
||||
end
|
||||
|
||||
# Referer
|
||||
|
|
|
@ -44,15 +44,10 @@ module Api
|
|||
|
||||
# Genera el Origin correcto a partir de la URL del sitio.
|
||||
#
|
||||
# En desarrollo devuelve el Origin enviado.
|
||||
#
|
||||
# XXX: Si el sitio tiene varias URLs, hay que devolver la más
|
||||
# similar al Origin o vamos a estar generando errores de CORS.
|
||||
#
|
||||
# @see {https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin}
|
||||
# @return [String]
|
||||
def return_origin
|
||||
Rails.env.production? ? Site.find_by(name: site_id).url : origin
|
||||
site&.deploys&.find_by_hostname(origin_hostname)&.url
|
||||
end
|
||||
|
||||
# La cookie no es accesible a través de JS y todo su contenido
|
||||
|
@ -63,6 +58,8 @@ module Api
|
|||
# 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'
|
||||
|
|
|
@ -118,11 +118,6 @@ module Api
|
|||
raise NotImplementedError
|
||||
end
|
||||
|
||||
# Encuentra el sitio o devuelve nulo
|
||||
def site
|
||||
@site ||= Site.find_by(name: site_id)
|
||||
end
|
||||
|
||||
# Genera un registro con información básica para debug, quizás no
|
||||
# quede asociado a ningún sitio.
|
||||
#
|
||||
|
|
|
@ -27,6 +27,13 @@ class Deploy < ApplicationRecord
|
|||
# Cada deploy puede implementar su propia validación
|
||||
validates :hostname, hostname: true, unless: :implements_hostname_validation?
|
||||
|
||||
# Retrocompatibilidad: Encuentra el site_name a partir del hostname.
|
||||
#
|
||||
# @return [String,Nil]
|
||||
def self.site_name_from_hostname(hostname)
|
||||
where(hostname: hostname).includes(:site).pluck(:name).first
|
||||
end
|
||||
|
||||
# Genera el hostname
|
||||
#
|
||||
# @return [String]
|
||||
|
|
|
@ -114,8 +114,8 @@ module Api
|
|||
create :rol, site: @site
|
||||
end
|
||||
|
||||
get v1_site_contact_cookie_url(@site.name, **@host)
|
||||
post v1_site_contact_url(site_id: @site.name, form: :contacto, **@host),
|
||||
get v1_site_contact_cookie_url(@site.hostname, **@host)
|
||||
post v1_site_contact_url(site_id: @site.hostname, form: :contacto, **@host),
|
||||
headers: { origin: @site.url },
|
||||
params: {
|
||||
name: SecureRandom.hex,
|
||||
|
@ -130,6 +130,34 @@ module Api
|
|||
assert_equal redirect, response.headers['Location']
|
||||
assert_equal 2, ActionMailer::Base.deliveries.size
|
||||
end
|
||||
|
||||
test 'algunos navegadores no soportan Origin' do
|
||||
ActionMailer::Base.deliveries.clear
|
||||
|
||||
@site.update name: 'example'
|
||||
|
||||
redirect = "#{@site.url}?thanks"
|
||||
|
||||
10.times do
|
||||
create :rol, site: @site
|
||||
end
|
||||
|
||||
get v1_site_contact_cookie_url(@site.hostname, **@host)
|
||||
post v1_site_contact_url(site_id: @site.hostname, form: :contacto, **@host),
|
||||
headers: { referer: @site.url },
|
||||
params: {
|
||||
name: SecureRandom.hex,
|
||||
pronouns: SecureRandom.hex,
|
||||
contact: SecureRandom.hex,
|
||||
from: "#{SecureRandom.hex}@sutty.nl",
|
||||
body: SecureRandom.hex,
|
||||
consent: true,
|
||||
redirect: redirect
|
||||
}
|
||||
|
||||
assert_equal redirect, response.headers['Location']
|
||||
assert_equal 2, ActionMailer::Base.deliveries.size
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue