Изменение адреса электронной почты пользователя

Я немного запутался в процессе, когда администратор меняет адрес электронной почты пользователя.

Есть вещи, которые я просто не понимаю, и есть одна ошибка (именно поэтому я пишу это в bug, а не в Support).

  • Согласно этому pull request, процесс должен работать следующим образом:

Когда администратор меняет email пользователя со страницы настроек этого пользователя:

  • Пользователю не отправляется письмо для подтверждения смены email. Вместо этого ему отправляется письмо для сброса пароля, чтобы он мог установить пароль для своей учетной записи на новый адрес электронной почты.
  • Пользователю по-прежнему отправляется письмо на старый адрес электронной почты с уведомлением о том, что адрес был изменен.

#1 Я не понимаю, почему отправляется письмо для сброса пароля («чтобы они могли установить пароль для своей учетной записи»). Им же не нужно менять пароль? И пользовательский опыт запутанный: пользователь не ожидает письма для сброса пароля, нет сопутствующего текста, в письме просто написано: «Кто-то запросил сброс вашего пароля на [название форума]».

#2 Это письмо для сброса пароля отправляется на старый адрес вместо нового адреса электронной почты.

Хотя email пользователя обновляется в update_user_email на строке 46, объект @user не перезагружается и все еще содержит старый адрес электронной почты.

#3 Если действующим пользователем является администратор, а пользователь, над которым совершаются действия, не является сотрудником, то письмо с подтверждением не отправляется, как указано в спецификации выше. Тем не менее, после смены адреса электронной почты администратор получает следующее сообщение об успехе: «Мы отправили письмо на этот адрес. Пожалуйста, следуйте инструкциям для подтверждения».

#4 Почему пользователю не нужно подтверждать свой новый адрес электронной почты? В pull request есть ссылка на эту тему, но, кажется, в ней отсутствуют многие сообщения. Однако в теме все еще упоминается: «Для обычного пользователя единственным адресом электронной почты, который должен быть подтвержден, является НОВЫЙ адрес». РЕДАКТИРОВАНИЕ: О, подождите, см. #6 / #7.

#5 Этот процесс, когда администратор меняет email пользователя, обычно используется, когда старый адрес электронной почты больше недоступен (предполагаю?). Почему тогда все еще отправляется уведомление на старый адрес?

#6 Когда этот пользователь пытается войти в систему, появляется всплывающее окно:

Вы пока не можете войти. Ранее мы отправили вам письмо с активацией на старый адрес электронной почты. Пожалуйста, следуйте инструкциям в этом письме, чтобы активировать свою учетную запись.

  • такого письма не было
  • упоминается старый адрес электронной почты

При нажатии кнопки «Отправить повторно» появляется сообщение:

Мы отправили вам еще одно письмо с активацией на новый адрес электронной почты. Это может занять несколько минут; обязательно проверьте папку «Спам».

#7 Это письмо с активацией действительно приходит на новый адрес электронной почты и имеет заголовок «Подтвердите свою новую учетную запись» (а не «Подтвердите свой новый адрес электронной почты»).

Разве это не должно быть просто так:

Одно письмо отправляется на новый адрес электронной почты со следующим текстом: «Ваш адрес электронной почты был изменен [имя администратора]. Пожалуйста, нажмите на следующую ссылку для подтверждения [ссылка]».

Редактирование: #8 Адрес электронной почты можно изменить администратором на публичной странице профиля пользователя (/u/username), но не со страницы администратора для этого пользователя (/admin/users/id/username). Это противоречит интуиции.

10 лайков

Можно воспроизвести это @tshenry? Мы допустили регрессию здесь?

2 лайка

Сначала я опишу текущий процесс, как я его наблюдаю (это совпадает с тем, что изложил @RGJ, если не полностью, то в большинстве случаев):

  1. Администратор переходит к настройкам обычного пользователя (не сотрудника) и меняет его адрес электронной почты:

    После отправки администратор видит следующее сообщение:

    Мы отправили письмо на этот адрес. Пожалуйста, следуйте инструкциям для подтверждения.

  2. Указанное выше сообщение выглядит неточным, поскольку ДВА письма отправляются на старый адрес электронной почты:

    [Demo] Ваш адрес электронной почты был изменен

    Это автоматическое сообщение информирует вас о том, что ваш адрес электронной почты для
    Demo был изменен. Если это было сделано по ошибке, пожалуйста, свяжитесь с
    администратором сайта.

    Ваш адрес электронной почты изменен на:

    new@email.com

    [Demo] Сброс пароля

    Кто-то запросил сброс вашего пароля на Demo.

    Если это сделали не вы, вы можете спокойно проигнорировать это письмо.

    Нажмите на следующую ссылку, чтобы выбрать новый пароль:
    https://example.discourse.site/u/password-reset/74d53d7d2cf20dsbc360614844c653s2

  3. Я протестировал три отдельных сценария с этого момента. Каждый пункт списка представляет собой отдельный сценарий:

    • Пользователь имеет доступ к старому адресу электронной почты и переходит по ссылке для сброса пароля. После обновления пароля он входит в систему. Оттуда он может войти, используя свое имя пользователя или СТАРЫЙ адрес электронной почты. Новый адрес, похоже, еще не активен.

    • Пользователь пытается войти, используя свое имя пользователя или новый адрес электронной почты, и получает следующее:

      Вариант 1: Нажатие кнопки «Отправить повторно» отображает следующее сообщение (обратите внимание, что на этот раз в нем указан новый адрес электронной почты):

      Письмо действительно отправляется на новый адрес электронной почты:

      [Demo] Подтвердите свою новую учетную запись

      Добро пожаловать в Demo!

      Нажмите на следующую ссылку, чтобы подтвердить и активировать свою новую учетную запись:
      https://example.discourse.site/u/activate-account/74d53d7d2cf20dsbc360614844c653s2

      Если ссылка выше не кликабельна, попробуйте скопировать и вставить её в адресную строку вашего веб-браузера.

      Переход по ссылке ведет через несколько страниц активации новой учетной записи. В итоге пользователь успешно входит в систему. С этого момента пользователь может входить, используя свое имя пользователя или СТАРЫЙ адрес электронной почты. Новый адрес, похоже, еще не активен.

      Вариант 2: Нажатие кнопки «Изменить адрес электронной почты» показывает следующее. Кнопка «Обновить адрес электронной почты» отключена, когда новый адрес введен в текстовое поле, что подразумевает его активацию (но это, кажется, не так).

    • Пользователь инициирует сброс пароля. Письмо отправляется на новый адрес электронной почты, и пользователь может войти, используя ссылку. Как и в других сценариях, пользователь может войти, используя свое имя пользователя или СТАРЫЙ адрес электронной почты. Новый адрес, похоже, еще не активен.

Итак, проблема определенно воспроизводится. Трудно четко описать это словами, но надеюсь, что между оригинальным постом и этим описанием всё станет ясно. Очевидно, что есть несколько моментов, которые требуют исправления.

@martin, я знаю, что вы ранее работали с этой частью ядра. Не могли бы вы высказать своё мнение, когда у вас будет минутка?

9 лайков

Почему это регрессировало? :thinking:

редактирование: Я тоже могу подтвердить, что это регрессировало. При редактировании email обычного пользователя подтверждение и прочее отправляется на СТАРЫЙ email. Раньше это работало иначе..

4 лайка

Это чувство неловкого узнавания, когда читаешь описание цитируемого pull request и понимаешь, что виновник — это ты…

Спасибо за подробные инструкции @tshenry и @RGJ. Я поставлю это в начало списка задач на эту неделю.

4 лайка

Хорошо, теперь я во всём разобрался и изучил удалённые комментарии в старой теме для истории. Я нашёл это сообщение от @sam, которое теперь вспомнил:

Ситуация с сбросом адреса электронной почты администратором сильно отличается: это скорее сброс администратором адреса электронной почты и пароля. Ведь если у пользователя есть доступ к аккаунту, он может сделать всё это самостоятельно через сервис.

То есть мы утверждаем, что поскольку именно администратор меняет адрес электронной почты, должно отправляться письмо для сброса пароля? Ведь если бы у пользователя был доступ к старому адресу, он мог бы просто… войти в систему и сделать это сам? Однако письмо для сброса пароля также выполняет функцию подтверждения. Без завершения процесса сброса пароля (что сейчас невозможно, так как письмо отправляется на старый адрес) новый адрес не считается «подтверждённым», и именно это вызывает появление модального окна:

Проблема, при которой письмо для сброса пароля отправляется на старый адрес, легко исправляется, и мы хотя бы перейдём в состояние, где процесс сброса можно будет завершить:

Кроме того, поскольку в настоящее время письмо для сброса пароля отправляется на старый адрес, при его подтверждении подтверждается неправильный адрес, и адрес электронной почты пользователя снова меняется на старый.

Я изменю сообщение для администратора, который меняет адрес электронной почты, чтобы чётко донести до него, что пользователь должен перейти по ссылке в новом письме и изменить пароль, чтобы изменения вступили в полную силу (а также исправить проблему с неправильным адресом).

4 лайка

Подождите. Я не понимаю этого.

Существует разница между тем, что пользователь имеет доступ к старому адресу электронной почты, и тем, что пользователю требуется сброс пароля для его учётной записи Discourse. Первое абсолютно не подразумевает второе; это совершенно разные ситуации.

Значительная часть изменений адреса электронной почты администратором происходит также потому, что пользователь не знает, как это сделать, или потому, что администратору нужно временно снять ограничение email_editable = false.

Меня очень сбивает с толку то, что сброс пароля одновременно служит подтверждением адреса электронной почты. Лично я даже не стал бы отвечать на письмо для сброса пароля, ведь я его не запрашивал, и я бы не понял, что это необходимый шаг подтверждения (и я думаю, что это не так; обычного письма для подтверждения было бы достаточно?)

4 лайка

Возможно, это связано со следующим:

Когда один из пользователей моего форума сегодня пытается сбросить пароль (используя последнюю версию Discourse на момент сегодняшнего утра), он получает письмо, но затем возникает ошибка при переходе по ссылке из письма:

Эта ошибка возникает в нескольких браузерах, и у пользователя не установлен блокировщик рекламы.

Когда я перехожу на страницу настроек его учётной записи и нажимаю «Отправить письмо для сброса пароля», там также появляется сообщение об ошибке:

Прежде чем рядом с кнопкой появится надпись «(ошибка)», она кратко показывает «(отправка письма)». Однако, похоже, письмо так и не было отправлено. Я могу подтвердить, что другие письма форума сегодня отправляются нормально.

Эта функция ранее работала без проблем… похоже, что проблема возникла где-то в течение последней недели.

Проверьте логи ошибок Discourse в веб-браузере, войдя в систему как администратор. Там должен быть отчёт об ошибке с более подробной информацией.

Вот запись об ошибке:

398 Исключение задачи: Указанный источник копирования превышает максимально допустимый размер для источника копирования: 5368709120

aws-sdk-core-3.99.1/lib/seahorse/client/plugins/raise_response_errors.rb:15:in `call'

aws-sdk-s3-1.66.0/lib/aws-sdk-s3/plugins/sse_cpk.rb:22:in `call'

aws-sdk-s3-1.66.0/lib/aws-sdk-s3/plugins/dualstack.rb:26:in `call'

aws-sdk-s3-1.66.0/lib/aws-sdk-s3/plugins/accelerate.rb:35:in `call'

aws-sdk-core-3.99.1/lib/aws-sdk-core/plugins/jsonvalue_converter.rb:20:in `call'

aws-sdk-core-3.99.1/lib/aws-sdk-core/plugins/idempotency_token.rb:17:in `call'

aws-sdk-core-3.99.1/lib/aws-sdk-core/plugins/param_converter.rb:24:in `call'

aws-sdk-core-3.99.1/lib/aws-sdk-core/plugins/response_paging.rb:10:in `call'

aws-sdk-core-3.99.1/lib/seahorse/client/plugins/response_target.rb:23:in `call'

aws-sdk-core-3.99.1/lib/seahorse/client/request.rb:70:in `send_request'

aws-sdk-s3-1.66.0/lib/aws-sdk-s3/client.rb:1108:in `copy_object'

/var/www/discourse/lib/backup_restore/s3_backup_store.rb:61:in `block in vacate_legacy_prefix'

/var/www/discourse/lib/backup_restore/s3_backup_store.rb:60:in `each'

/var/www/discourse/lib/backup_restore/s3_backup_store.rb:60:in `vacate_legacy_prefix'

/var/www/discourse/app/jobs/onceoff/vacate_legacy_prefix_backups.rb:7:in `execute_onceoff'

/var/www/discourse/app/jobs/onceoff/onceoff.rb:25:in `execute'

/var/www/discourse/app/jobs/base.rb:232:in `block (2 levels) in perform'

rails_multisite-2.5.0/lib/rails_multisite/connection_management.rb:76:in `with_connection'

/var/www/discourse/app/jobs/base.rb:221:in `block in perform'

/var/www/discourse/app/jobs/base.rb:217:in `each'

/var/www/discourse/app/jobs/base.rb:217:in `perform'

sidekiq-6.1.2/lib/sidekiq/processor.rb:196:in `execute_job'

sidekiq-6.1.2/lib/sidekiq/processor.rb:164:in `block (2 levels) in process'

sidekiq-6.1.2/lib/sidekiq/middleware/chain.rb:138:in `block in invoke'

/var/www/discourse/lib/sidekiq/pausable.rb:138:in `call'

sidekiq-6.1.2/lib/sidekiq/middleware/chain.rb:140:in `block in invoke'

sidekiq-6.1.2/lib/sidekiq/middleware/chain.rb:143:in `invoke'

sidekiq-6.1.2/lib/sidekiq/processor.rb:163:in `block in process'

sidekiq-6.1.2/lib/sidekiq/processor.rb:136:in `block (6 levels) in dispatch'

sidekiq-6.1.2/lib/sidekiq/job_retry.rb:111:in `local'

sidekiq-6.1.2/lib/sidekiq/processor.rb:135:in `block (5 levels) in dispatch'

sidekiq-6.1.2/lib/sidekiq.rb:38:in `block in <module:Sidekiq>'

sidekiq-6.1.2/lib/sidekiq/processor.rb:131:in `block (4 levels) in dispatch'

sidekiq-6.1.2/lib/sidekiq/processor.rb:257:in `stats'

sidekiq-6.1.2/lib/sidekiq/processor.rb:126:in `block (3 levels) in dispatch'

sidekiq-6.1.2/lib/sidekiq/job_logger.rb:13:in `call'

sidekiq-6.1.2/lib/sidekiq/processor.rb:125:in `block (2 levels) in dispatch'

sidekiq-6.1.2/lib/sidekiq/job_retry.rb:78:in `global'

sidekiq-6.1.2/lib/sidekiq/processor.rb:124:in `block in dispatch'

sidekiq-6.1.2/lib/sidekiq/logger.rb:10:in `with'

sidekiq-6.1.2/lib/sidekiq/job_logger.rb:33:in `prepare'

sidekiq-6.1.2/lib/sidekiq/processor.rb:123:in `dispatch'

sidekiq-6.1.2/lib/sidekiq/processor.rb:162:in `process'

sidekiq-6.1.2/lib/sidekiq/processor.rb:78:in `process_one'

sidekiq-6.1.2/lib/sidekiq/processor.rb:68:in `run'

sidekiq-6.1.2/lib/sidekiq/util.rb:15:in `watchdog'

sidekiq-6.1.2/lib/sidekiq/util.rb:24:in `block in safe_thread'
1 лайк

Нет, это абсолютно не связано.
Попробуйте очистить логи и принудительно вызвать эту ошибку, а затем снова проверьте логи.

Тогда после возникновения ошибки логи остаются пустыми.

Я понимаю ваши доводы; для меня вчерашний момент, когда сброс пароля использовался как подтверждение, стал камнем преткновения. Мне кажется, это могло бы быть дополнительной опцией для администратора при смене email-адреса пользователя: галочка с надписью «Также сбросить пароль пользователя». Я собираюсь объединить мой PR с исправлением в текущем виде, поскольку процесс сейчас полностью сломан.

Я хотел бы, чтобы @sam высказался относительно нового процесса/потока, так как Сам изначально обсуждал причины, лежащие в основе процесса сброса пароля:

  1. Администратор меняет email-адрес пользователя. У него есть возможность одновременно сбросить пароль.
  2. Пользователь получает письмо на новый адрес с просьбой подтвердить смену email-адреса.
    • Если он отвечает «Да», email-адрес меняется. Мы отправляем письмо на старый адрес с уведомлением о смене email.
    • Если он отвечает «Нет», ничего не делаем.
  3. Если администратор указал, что хочет сброс пароля в пункте 1, то сразу после подтверждения пользователем смены email-адреса ему на новый адрес отправляется письмо для сброса пароля.

Я думаю, что это было бы гораздо понятнее, и сброс пароля не имел бы никакого отношения к подтверждению смены email-адреса.

2 лайка

Да, я не понимаю, почему эти две вещи вообще должны быть связаны?

1 лайк

Я вижу 1 новый объединённый коммит, который порадует всех :smiley:

3 лайка

Спасибо, это просто внесёт исправление для «полностью сломанного» состояния дел. Скоро последует ещё один PR!

Так было сделано по итогам обсуждений в предыдущей теме с Сэмом. Я перейду к новому процессу, чтобы развеять путаницу и разорвать связь между несвязанными вещами.

4 лайка

Я только что объединил этот PR, который делает следующее:

  • Изменяет процесс смены email в админке для пользователя, чтобы пользователю отправлялось письмо для подтверждения изменения.
  • Теперь мы фиксируем, кто инициировал запрос на смену email.
  • Если запрос инициирован администратором, а не самим пользователем, это указывается в письме, отправленном пользователю.
  • Также мы делаем маршрут подтверждения смены email доступным для анонимных пользователей, чтобы ссылка могла быть нажата даже в случае, если у пользователя нет доступа к своему аккаунту. Если пользователь авторизован, мы гарантируем, что подтверждение соответствует текущему пользователю.

Надеюсь, теперь этот процесс станет гораздо понятнее!

4 лайка