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
|
# TODO: Generar API v2 que use solo el hostname y no haya que
|
||||||
# pasar site_id como parámetro redundante.
|
# pasar site_id como parámetro redundante.
|
||||||
def site_id
|
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
|
end
|
||||||
|
|
||||||
# Referer
|
# Referer
|
||||||
|
|
|
@ -44,15 +44,10 @@ module Api
|
||||||
|
|
||||||
# Genera el Origin correcto a partir de la URL del sitio.
|
# 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}
|
# @see {https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin}
|
||||||
# @return [String]
|
# @return [String]
|
||||||
def return_origin
|
def return_origin
|
||||||
Rails.env.production? ? Site.find_by(name: site_id).url : origin
|
site&.deploys&.find_by_hostname(origin_hostname)&.url
|
||||||
end
|
end
|
||||||
|
|
||||||
# La cookie no es accesible a través de JS y todo su contenido
|
# 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
|
# TODO: Volver configurable por sitio
|
||||||
expires = ENV.fetch('COOKIE_DURATION', '30').to_i.minutes
|
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-Origin'] = return_origin
|
||||||
headers['Access-Control-Allow-Credentials'] = true
|
headers['Access-Control-Allow-Credentials'] = true
|
||||||
headers['Vary'] = 'Origin'
|
headers['Vary'] = 'Origin'
|
||||||
|
|
|
@ -118,11 +118,6 @@ module Api
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
end
|
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
|
# Genera un registro con información básica para debug, quizás no
|
||||||
# quede asociado a ningún sitio.
|
# quede asociado a ningún sitio.
|
||||||
#
|
#
|
||||||
|
|
|
@ -27,6 +27,13 @@ class Deploy < ApplicationRecord
|
||||||
# Cada deploy puede implementar su propia validación
|
# Cada deploy puede implementar su propia validación
|
||||||
validates :hostname, hostname: true, unless: :implements_hostname_validation?
|
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
|
# Genera el hostname
|
||||||
#
|
#
|
||||||
# @return [String]
|
# @return [String]
|
||||||
|
|
|
@ -114,8 +114,8 @@ module Api
|
||||||
create :rol, site: @site
|
create :rol, site: @site
|
||||||
end
|
end
|
||||||
|
|
||||||
get v1_site_contact_cookie_url(@site.name, **@host)
|
get v1_site_contact_cookie_url(@site.hostname, **@host)
|
||||||
post v1_site_contact_url(site_id: @site.name, form: :contacto, **@host),
|
post v1_site_contact_url(site_id: @site.hostname, form: :contacto, **@host),
|
||||||
headers: { origin: @site.url },
|
headers: { origin: @site.url },
|
||||||
params: {
|
params: {
|
||||||
name: SecureRandom.hex,
|
name: SecureRandom.hex,
|
||||||
|
@ -130,6 +130,34 @@ module Api
|
||||||
assert_equal redirect, response.headers['Location']
|
assert_equal redirect, response.headers['Location']
|
||||||
assert_equal 2, ActionMailer::Base.deliveries.size
|
assert_equal 2, ActionMailer::Base.deliveries.size
|
||||||
end
|
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
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue