From 7d7fcdc409b34b040218168499c558e0aa3d5e96 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 20 Mar 2023 16:08:37 -0300 Subject: [PATCH 01/11] fix: recuperar el comportamiento esperado #2123 --- app/controllers/usuaries_controller.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/controllers/usuaries_controller.rb b/app/controllers/usuaries_controller.rb index 6d02a35a..c60ea206 100644 --- a/app/controllers/usuaries_controller.rb +++ b/app/controllers/usuaries_controller.rb @@ -88,16 +88,16 @@ class UsuariesController < ApplicationController # TODO: Enviar invitación igual! Podemos no usar el Mailer de # DeviseInvitations y usar uno propio que contenga texto y se # envíe de todas formas. - usuarie = Usuarie.invite! email: invitacion.address, - skip_invitation: true + attributes = { email: invitacion.address } + options = { skip_invitation: true } + usuarie = Usuarie.invite! attributes, current_usuarie, options # No invitar al sitio si ya estaba en la lista! # # XXX: En este caso no estamos enviando ninguna invitación next if usuarie.sites.exists? @site.id - @site.roles << Rol.create(usuarie: usuarie, site: @site, - temporal: true, rol: invited_as) + @site.roles.create(usuarie: usuarie, temporal: true, rol: invited_as) # Invitamos después de crear el rol para que el correo de # invitación pueda recibir el sitio. From 61a23cb3d7945171ce08f56e469fcfcf4b666eb1 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 20 Mar 2023 16:54:00 -0300 Subject: [PATCH 02/11] =?UTF-8?q?fix:=20solo=20enviar=20invitaci=C3=B3n=20?= =?UTF-8?q?si=20le=20usuarie=20no=20existe?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/usuaries_controller.rb | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/app/controllers/usuaries_controller.rb b/app/controllers/usuaries_controller.rb index c60ea206..3dd78de1 100644 --- a/app/controllers/usuaries_controller.rb +++ b/app/controllers/usuaries_controller.rb @@ -82,26 +82,14 @@ class UsuariesController < ApplicationController # Enviar la invitación si es necesario y agregar al sitio invitaciones.each do |invitacion| - # Si la cuenta no existe, envía una invitación por correo, sino, - # no se envía nada - # - # TODO: Enviar invitación igual! Podemos no usar el Mailer de - # DeviseInvitations y usar uno propio que contenga texto y se - # envíe de todas formas. attributes = { email: invitacion.address } - options = { skip_invitation: true } - usuarie = Usuarie.invite! attributes, current_usuarie, options - # No invitar al sitio si ya estaba en la lista! - # - # XXX: En este caso no estamos enviando ninguna invitación + usuarie = Usuarie.find_by attributes + usuarie ||= Usuarie.invite! attributes, current_usuarie + next if usuarie.sites.exists? @site.id @site.roles.create(usuarie: usuarie, temporal: true, rol: invited_as) - - # Invitamos después de crear el rol para que el correo de - # invitación pueda recibir el sitio. - usuarie.deliver_invitation end redirect_to site_usuaries_path(@site) From 92fa2b89324a9973d31bc5acdb3185246a12db06 Mon Sep 17 00:00:00 2001 From: f Date: Mon, 20 Mar 2023 16:59:27 -0300 Subject: [PATCH 03/11] fix: no llevar registro de quien se conoce con quien aunque es un poco obvio al mirar la lista de usuaries de un sitio --- app/controllers/usuaries_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/usuaries_controller.rb b/app/controllers/usuaries_controller.rb index 3dd78de1..9cc756f7 100644 --- a/app/controllers/usuaries_controller.rb +++ b/app/controllers/usuaries_controller.rb @@ -85,7 +85,7 @@ class UsuariesController < ApplicationController attributes = { email: invitacion.address } usuarie = Usuarie.find_by attributes - usuarie ||= Usuarie.invite! attributes, current_usuarie + usuarie ||= Usuarie.invite! attributes next if usuarie.sites.exists? @site.id From 362e45b51d0bb67fbf4f88d19ead72c35b7f52dc Mon Sep 17 00:00:00 2001 From: f Date: Mon, 20 Mar 2023 17:17:53 -0300 Subject: [PATCH 04/11] fix: efectivamente ignorar mails que ya son usuaries de este sitio --- app/controllers/usuaries_controller.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/controllers/usuaries_controller.rb b/app/controllers/usuaries_controller.rb index 9cc756f7..2dd3ea99 100644 --- a/app/controllers/usuaries_controller.rb +++ b/app/controllers/usuaries_controller.rb @@ -84,11 +84,11 @@ class UsuariesController < ApplicationController invitaciones.each do |invitacion| attributes = { email: invitacion.address } + next if Usuarie.where(id: @site.roles.pluck(:usuarie_id)).find_by(attributes) + usuarie = Usuarie.find_by attributes usuarie ||= Usuarie.invite! attributes - next if usuarie.sites.exists? @site.id - @site.roles.create(usuarie: usuarie, temporal: true, rol: invited_as) end From 11e503061cf3dde80bdf5100fe268ecc9fbbdb2d Mon Sep 17 00:00:00 2001 From: f Date: Mon, 20 Mar 2023 17:22:40 -0300 Subject: [PATCH 05/11] =?UTF-8?q?fix:=20enviar=20invitaci=C3=B3n=20sin=20l?= =?UTF-8?q?ink?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Usuarie#deliver_invitation además generaba un token cuando no era necesario y esto es lo que hacía que les usuaries quedaran flotando. --- app/controllers/usuaries_controller.rb | 5 ++++- .../mailer/invitation_instructions.html.haml | 17 +++++++++------- .../mailer/invitation_instructions.text.haml | 20 +++++++++++-------- config/locales/devise_invitable.en.yml | 1 + config/locales/devise_invitable.es.yml | 1 + 5 files changed, 28 insertions(+), 16 deletions(-) diff --git a/app/controllers/usuaries_controller.rb b/app/controllers/usuaries_controller.rb index 2dd3ea99..7621489e 100644 --- a/app/controllers/usuaries_controller.rb +++ b/app/controllers/usuaries_controller.rb @@ -86,7 +86,10 @@ class UsuariesController < ApplicationController next if Usuarie.where(id: @site.roles.pluck(:usuarie_id)).find_by(attributes) - usuarie = Usuarie.find_by attributes + usuarie = Usuarie.find_by(attributes).tap do |u| + u.send(:send_devise_notification, :invitation_instructions, nil) + end + usuarie ||= Usuarie.invite! attributes @site.roles.create(usuarie: usuarie, temporal: true, rol: invited_as) diff --git a/app/views/devise/mailer/invitation_instructions.html.haml b/app/views/devise/mailer/invitation_instructions.html.haml index 74193878..e1fe6812 100644 --- a/app/views/devise/mailer/invitation_instructions.html.haml +++ b/app/views/devise/mailer/invitation_instructions.html.haml @@ -8,12 +8,15 @@ %h1= site.title %p= site.description -%p= link_to t('devise.mailer.invitation_instructions.accept'), - accept_invitation_url(@resource, invitation_token: @token) +- if @resource.created_by_invite? + %p= link_to t('devise.mailer.invitation_instructions.accept'), + accept_invitation_url(@resource, invitation_token: @token) -- if @resource.invitation_due_at - %p= t('devise.mailer.invitation_instructions.accept_until', - due_date: l(@resource.invitation_due_at, - format: :'devise.mailer.invitation_instructions.accept_until_format')) + - if @resource.invitation_due_at + %p= t('devise.mailer.invitation_instructions.accept_until', + due_date: l(@resource.invitation_due_at, + format: :'devise.mailer.invitation_instructions.accept_until_format')) -%p= t('devise.mailer.invitation_instructions.ignore') + %p= t('devise.mailer.invitation_instructions.ignore') +- else + %p= link_to t('devise.mailer.invitation_instructions.sign_in'), root_url diff --git a/app/views/devise/mailer/invitation_instructions.text.haml b/app/views/devise/mailer/invitation_instructions.text.haml index 16a9f0a8..353f2a12 100644 --- a/app/views/devise/mailer/invitation_instructions.text.haml +++ b/app/views/devise/mailer/invitation_instructions.text.haml @@ -9,11 +9,15 @@ \ = site.description \ -= accept_invitation_url(@resource, invitation_token: @token) -\ -- if @resource.invitation_due_at - = t('devise.mailer.invitation_instructions.accept_until', - due_date: l(@resource.invitation_due_at, - format: :'devise.mailer.invitation_instructions.accept_until_format')) -\ -= t('devise.mailer.invitation_instructions.ignore') +- if @resource.created_by_invite? + = accept_invitation_url(@resource, invitation_token: @token) + \ + - if @resource.invitation_due_at + = t('devise.mailer.invitation_instructions.accept_until', + due_date: l(@resource.invitation_due_at, + format: :'devise.mailer.invitation_instructions.accept_until_format')) + \ + = t('devise.mailer.invitation_instructions.ignore') +- else + = root_url(change_locale_to: @resource.lang) + = t('devise.mailer.invitation_instructions.sign_in') diff --git a/config/locales/devise_invitable.en.yml b/config/locales/devise_invitable.en.yml index f6bfee40..39238140 100644 --- a/config/locales/devise_invitable.en.yml +++ b/config/locales/devise_invitable.en.yml @@ -23,6 +23,7 @@ en: accept: "Accept invitation" accept_until: "This invitation will be due in %{due_date}." ignore: "If you don't want to accept the invitation, please ignore this email. Your account won't be created until you access the link above and set your password." + sign_in: "Sign in to your account to accept or decline the invitation." time: formats: devise: diff --git a/config/locales/devise_invitable.es.yml b/config/locales/devise_invitable.es.yml index 144d6df6..e83a703c 100644 --- a/config/locales/devise_invitable.es.yml +++ b/config/locales/devise_invitable.es.yml @@ -23,6 +23,7 @@ es: accept: "Aceptar la invitación" accept_until: "La invitación vencerá el %{due_date}." ignore: "Si no querés aceptar la invitación, por favor ignora este correo. Tu cuenta no será creada hasta que aceptes la invitación y configures una contraseña." + sign_in: "Iniciá sesión con tu cuenta para aceptar o rechazar la invitación." time: formats: devise: From 8fa2991bb1771288b8cad46fc30094ed96a365a1 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 23 Mar 2023 11:44:47 -0300 Subject: [PATCH 06/11] =?UTF-8?q?fix:=20enviar=20la=20invitaci=C3=B3n=20lu?= =?UTF-8?q?ego=20de=20crear=20el=20rol=20#12728?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit de otra forma les usuaries que ya tienen sitios reciben una invitación a un sitio que no es y les que no tienen sitios no reciben nada porque hay un error. --- app/controllers/usuaries_controller.rb | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/app/controllers/usuaries_controller.rb b/app/controllers/usuaries_controller.rb index 7621489e..3f672110 100644 --- a/app/controllers/usuaries_controller.rb +++ b/app/controllers/usuaries_controller.rb @@ -83,16 +83,19 @@ class UsuariesController < ApplicationController # Enviar la invitación si es necesario y agregar al sitio invitaciones.each do |invitacion| attributes = { email: invitacion.address } + options = { skip_invitation: true } next if Usuarie.where(id: @site.roles.pluck(:usuarie_id)).find_by(attributes) - usuarie = Usuarie.find_by(attributes).tap do |u| - u.send(:send_devise_notification, :invitation_instructions, nil) + usuarie = Usuarie.find_by attributes + usuarie ||= Usuarie.invite!(attributes, nil, options).tap do |u| + u.generate_invitation_token! end - usuarie ||= Usuarie.invite! attributes - @site.roles.create(usuarie: usuarie, temporal: true, rol: invited_as) + + # XXX: La invitación tiene que ser enviada luego de crear el rol + usuarie.send(:send_devise_notification, :invitation_instructions, nil) end redirect_to site_usuaries_path(@site) From 1ac83140d60353ffc773622b75bb5c531264af65 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 23 Mar 2023 15:32:54 -0300 Subject: [PATCH 07/11] =?UTF-8?q?fix:=20no=20enviar=20la=20invitaci=C3=B3n?= =?UTF-8?q?=20hasta=20=C3=BAltimo=20momento?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/usuaries_controller.rb | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/app/controllers/usuaries_controller.rb b/app/controllers/usuaries_controller.rb index 3f672110..ab116572 100644 --- a/app/controllers/usuaries_controller.rb +++ b/app/controllers/usuaries_controller.rb @@ -82,20 +82,19 @@ class UsuariesController < ApplicationController # Enviar la invitación si es necesario y agregar al sitio invitaciones.each do |invitacion| - attributes = { email: invitacion.address } - options = { skip_invitation: true } + attributes = { email: invitacion.address, skip_invitation: true } next if Usuarie.where(id: @site.roles.pluck(:usuarie_id)).find_by(attributes) usuarie = Usuarie.find_by attributes - usuarie ||= Usuarie.invite!(attributes, nil, options).tap do |u| - u.generate_invitation_token! + usuarie ||= Usuarie.invite!(attributes).tap do |u| + u.send :generate_invitation_token! end @site.roles.create(usuarie: usuarie, temporal: true, rol: invited_as) # XXX: La invitación tiene que ser enviada luego de crear el rol - usuarie.send(:send_devise_notification, :invitation_instructions, nil) + usuarie.deliver_invitation end redirect_to site_usuaries_path(@site) From fce5c0d90b38edef44e8fdae37ec8b87c5758072 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 23 Mar 2023 15:38:46 -0300 Subject: [PATCH 08/11] =?UTF-8?q?fix:=20hacer=20todo=20en=20una=20transacc?= =?UTF-8?q?i=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/usuaries_controller.rb | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/app/controllers/usuaries_controller.rb b/app/controllers/usuaries_controller.rb index ab116572..84bcc13f 100644 --- a/app/controllers/usuaries_controller.rb +++ b/app/controllers/usuaries_controller.rb @@ -86,15 +86,17 @@ class UsuariesController < ApplicationController next if Usuarie.where(id: @site.roles.pluck(:usuarie_id)).find_by(attributes) - usuarie = Usuarie.find_by attributes - usuarie ||= Usuarie.invite!(attributes).tap do |u| - u.send :generate_invitation_token! + Usuarie.transaction do + usuarie = Usuarie.find_by attributes + usuarie ||= Usuarie.invite!(attributes).tap do |u| + u.send :generate_invitation_token! + end + + @site.roles.create(usuarie: usuarie, temporal: true, rol: invited_as) + + # XXX: La invitación tiene que ser enviada luego de crear el rol + usuarie.deliver_invitation end - - @site.roles.create(usuarie: usuarie, temporal: true, rol: invited_as) - - # XXX: La invitación tiene que ser enviada luego de crear el rol - usuarie.deliver_invitation end redirect_to site_usuaries_path(@site) From 732db666c7bf10d03696c243d54c351bb8c4e85b Mon Sep 17 00:00:00 2001 From: f Date: Thu, 23 Mar 2023 15:42:20 -0300 Subject: [PATCH 09/11] =?UTF-8?q?fix:=20usar=20el=20=C3=BAltimo=20sitio=20?= =?UTF-8?q?al=20que=20todav=C3=ADa=20no=20aceptamos=20invitaci=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/views/devise/mailer/invitation_instructions.html.haml | 2 +- app/views/devise/mailer/invitation_instructions.text.haml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/devise/mailer/invitation_instructions.html.haml b/app/views/devise/mailer/invitation_instructions.html.haml index e1fe6812..bc9d9e4e 100644 --- a/app/views/devise/mailer/invitation_instructions.html.haml +++ b/app/views/devise/mailer/invitation_instructions.html.haml @@ -1,4 +1,4 @@ -- site = @resource.sites.last +- site = @resource.roles.where(temporal: true).last&.site %p= t('devise.mailer.invitation_instructions.hello', email: @resource.email) diff --git a/app/views/devise/mailer/invitation_instructions.text.haml b/app/views/devise/mailer/invitation_instructions.text.haml index 353f2a12..a1360bb0 100644 --- a/app/views/devise/mailer/invitation_instructions.text.haml +++ b/app/views/devise/mailer/invitation_instructions.text.haml @@ -1,4 +1,4 @@ -- site = @resource.sites.last +- site = @resource.roles.where(temporal: true).last&.site = t('devise.mailer.invitation_instructions.hello', email: @resource.email) \ From 1fa37b20e1ee5f218e98b21da518927a2512f953 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 23 Mar 2023 15:47:06 -0300 Subject: [PATCH 10/11] fix: solo invitar una vez --- app/views/devise/mailer/invitation_instructions.html.haml | 2 +- app/views/devise/mailer/invitation_instructions.text.haml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/devise/mailer/invitation_instructions.html.haml b/app/views/devise/mailer/invitation_instructions.html.haml index bc9d9e4e..3cb9704e 100644 --- a/app/views/devise/mailer/invitation_instructions.html.haml +++ b/app/views/devise/mailer/invitation_instructions.html.haml @@ -8,7 +8,7 @@ %h1= site.title %p= site.description -- if @resource.created_by_invite? +- if @resource.created_by_invite? && !@resource.invitation_accepted? %p= link_to t('devise.mailer.invitation_instructions.accept'), accept_invitation_url(@resource, invitation_token: @token) diff --git a/app/views/devise/mailer/invitation_instructions.text.haml b/app/views/devise/mailer/invitation_instructions.text.haml index a1360bb0..2050c19c 100644 --- a/app/views/devise/mailer/invitation_instructions.text.haml +++ b/app/views/devise/mailer/invitation_instructions.text.haml @@ -9,7 +9,7 @@ \ = site.description \ -- if @resource.created_by_invite? +- if @resource.created_by_invite? && !@resource.invitation_accepted? = accept_invitation_url(@resource, invitation_token: @token) \ - if @resource.invitation_due_at From 1bfff4dfdb72ebdd676c324d0a60bcf16f5b2c5a Mon Sep 17 00:00:00 2001 From: f Date: Thu, 23 Mar 2023 16:24:53 -0300 Subject: [PATCH 11/11] fix: enviar las invitaciones luego de crear el rol --- app/controllers/usuaries_controller.rb | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/app/controllers/usuaries_controller.rb b/app/controllers/usuaries_controller.rb index 84bcc13f..074694f1 100644 --- a/app/controllers/usuaries_controller.rb +++ b/app/controllers/usuaries_controller.rb @@ -81,21 +81,25 @@ class UsuariesController < ApplicationController authorize SiteUsuarie.new(@site, current_usuarie) # Enviar la invitación si es necesario y agregar al sitio - invitaciones.each do |invitacion| - attributes = { email: invitacion.address, skip_invitation: true } - - next if Usuarie.where(id: @site.roles.pluck(:usuarie_id)).find_by(attributes) + invitaciones.each do |address| + next if Usuarie.where(id: @site.roles.pluck(:usuarie_id)).find_by_email(address) Usuarie.transaction do - usuarie = Usuarie.find_by attributes - usuarie ||= Usuarie.invite!(attributes).tap do |u| + usuarie = Usuarie.find_by_email(address) + usuarie ||= Usuarie.invite!({ email: address, skip_invitation: true }).tap do |u| u.send :generate_invitation_token! end - @site.roles.create(usuarie: usuarie, temporal: true, rol: invited_as) + role = @site.roles.create(usuarie: usuarie, temporal: true, rol: invited_as) # XXX: La invitación tiene que ser enviada luego de crear el rol - usuarie.deliver_invitation + if role.persisted? + usuarie.deliver_invitation + else + raise ArgumentError, role.errors.full_messages + end + rescue ArgumentError => e + ExceptionNotifier.notify_exception(e, data: { site: @site.name, address: address }) end end @@ -137,6 +141,8 @@ class UsuariesController < ApplicationController private # Traer todas las invitaciones que al menos tengan usuarie y dominio + # + # @return [Array] def invitaciones # XXX: Podríamos usar EmailAddress pero hace chequeos más lentos params[:invitaciones]&.tr("\r", '')&.split("\n")&.map do |m| @@ -145,7 +151,7 @@ class UsuariesController < ApplicationController nil end.compact.select do |m| m.local && m.domain - end + end.map(&:address) end # El tipo de invitación que tenemos que enviar, si alguien mandó