From 71df2a12e1c83354f7cab1a8fd785f9b92d74e81 Mon Sep 17 00:00:00 2001 From: Sebastian Jambor Date: Mon, 9 Jan 2023 20:32:14 +0100 Subject: [PATCH] one-click sign-up with autogenerated usernames --- Gemfile | 2 + Gemfile.lock | 8 ++++ .../auth/registrations_controller.rb | 29 +++++++++++- app/controllers/auth/roman.txt | 44 +++++++++++++++++++ app/views/auth/registrations/new.html.haml | 10 +---- config/environments/development.rb | 3 +- config/environments/production.rb | 2 +- 7 files changed, 87 insertions(+), 11 deletions(-) create mode 100644 app/controllers/auth/roman.txt diff --git a/Gemfile b/Gemfile index 6e5292d82..41c294010 100644 --- a/Gemfile +++ b/Gemfile @@ -158,3 +158,5 @@ gem 'concurrent-ruby', require: false gem 'connection_pool', require: false gem 'xorcist', '~> 1.1' gem 'cocoon', '~> 1.2' + +gem 'random_name_generator' diff --git a/Gemfile.lock b/Gemfile.lock index 2d7ee2df8..987f7d80d 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -549,6 +549,7 @@ GEM thor (~> 1.0) rainbow (3.1.1) rake (13.0.6) + random_name_generator (2.0.1) rdf (3.2.9) link_header (~> 0.0, >= 0.0.8) rdf-normalize (0.5.1) @@ -849,6 +850,7 @@ DEPENDENCIES rails-controller-testing (~> 1.0) rails-i18n (~> 6.0) rails-settings-cached (~> 0.6) + random_name_generator rdf-normalize (~> 0.5) redcarpet (~> 3.6) redis (~> 4.5) @@ -886,3 +888,9 @@ DEPENDENCIES webpacker (~> 5.4) webpush! xorcist (~> 1.1) + +RUBY VERSION + ruby 3.0.4p208 + +BUNDLED WITH + 2.2.33 diff --git a/app/controllers/auth/registrations_controller.rb b/app/controllers/auth/registrations_controller.rb index 540b04a6c..a53f10d81 100644 --- a/app/controllers/auth/registrations_controller.rb +++ b/app/controllers/auth/registrations_controller.rb @@ -1,5 +1,8 @@ # frozen_string_literal: true +require 'random_name_generator' +require 'securerandom' + class Auth::RegistrationsController < Devise::RegistrationsController include RegistrationSpamConcern @@ -45,6 +48,21 @@ class Auth::RegistrationsController < Devise::RegistrationsController end def build_resource(hash = nil) + + # hack to always use auto-generated usernames and passwords + if !hash.nil? + username = generate_name + password = SecureRandom.hex + + hash["account_attributes"] = { + "username": username.parameterize(separator: '_'), + "display_name": username + } + hash["email"] = "#{hash["account_attributes"]["username"]}@#{Rails.configuration.x.web_domain}" + hash["password"] = password + hash["password_confirmation"] = password + end + super(hash) resource.locale = I18n.locale @@ -62,7 +80,9 @@ class Auth::RegistrationsController < Devise::RegistrationsController end def after_sign_up_path_for(_resource) - auth_setup_path + # Hack to automatically visit the confirmation link after successful sign-up. + # This way we can use the default configuration but still get away without an email server. + "/auth/confirmation?confirmation_token=#{@user.confirmation_token}" end def after_sign_in_path_for(_resource) @@ -156,4 +176,11 @@ class Auth::RegistrationsController < Devise::RegistrationsController def set_cache_headers response.headers['Cache-Control'] = 'private, no-store' end + + @@first_name_generator = RandomNameGenerator.new(File.new("#{File.dirname(__FILE__)}/roman.txt")) + @@last_name_generator = RandomNameGenerator.new(RandomNameGenerator::FANTASY) + + def generate_name + "#{@@first_name_generator.compose(3)} #{@@last_name_generator.compose(2)}" + end end diff --git a/app/controllers/auth/roman.txt b/app/controllers/auth/roman.txt new file mode 100644 index 000000000..851d52538 --- /dev/null +++ b/app/controllers/auth/roman.txt @@ -0,0 +1,44 @@ +-a +-al +-au +c +-an +-ba +-be +-bi +-br +v +-da +-di +-do +-du +-e +-eu +c +-fa +bi +be +bo +bu +nul +v +gu +da +au +c -c +fri +gus ++tus ++ta ++lus ++la ++lius ++lia ++nus ++na ++es ++ius -c ++ia -c ++cus ++ca ++tor ++cio ++cia ++tin ++tia ++ssia -v diff --git a/app/views/auth/registrations/new.html.haml b/app/views/auth/registrations/new.html.haml index 0d8fd800f..40020b1f5 100644 --- a/app/views/auth/registrations/new.html.haml +++ b/app/views/auth/registrations/new.html.haml @@ -16,14 +16,8 @@ = render 'application/card', account: @invite.user.account .fields-group - = f.simple_fields_for :account do |ff| - = ff.input :display_name, wrapper: :with_label, label: false, required: false, input_html: { 'aria-label': t('simple_form.labels.defaults.display_name'), autocomplete: 'off', placeholder: t('simple_form.labels.defaults.display_name') } - = ff.input :username, wrapper: :with_label, label: false, required: true, input_html: { 'aria-label': t('simple_form.labels.defaults.username'), autocomplete: 'off', placeholder: t('simple_form.labels.defaults.username'), pattern: '[a-zA-Z0-9_]+', maxlength: 30 }, append: "@#{site_hostname}", hint: false - = f.input :email, placeholder: t('simple_form.labels.defaults.email'), required: true, input_html: { 'aria-label': t('simple_form.labels.defaults.email'), autocomplete: 'username' }, hint: false - = f.input :password, placeholder: t('simple_form.labels.defaults.password'), required: true, input_html: { 'aria-label': t('simple_form.labels.defaults.password'), autocomplete: 'new-password', minlength: User.password_length.first, maxlength: User.password_length.last }, hint: false - = f.input :password_confirmation, placeholder: t('simple_form.labels.defaults.confirm_password'), required: true, input_html: { 'aria-label': t('simple_form.labels.defaults.confirm_password'), autocomplete: 'new-password' }, hint: false - = f.input :confirm_password, as: :string, placeholder: t('simple_form.labels.defaults.honeypot', label: t('simple_form.labels.defaults.password')), required: false, input_html: { 'aria-label': t('simple_form.labels.defaults.honeypot', label: t('simple_form.labels.defaults.password')), autocomplete: 'off' }, hint: false - = f.input :website, as: :url, wrapper: :with_label, label: t('simple_form.labels.defaults.honeypot', label: 'Website'), required: false, input_html: { 'aria-label': t('simple_form.labels.defaults.honeypot', label: 'Website'), autocomplete: 'off' } + = f.input :confirm_password, as: :string, placeholder: t('simple_form.labels.defaults.honeypot', label: t('simple_form.labels.defaults.password')), required: false, input_html: { 'aria-label' => t('simple_form.labels.defaults.honeypot', label: t('simple_form.labels.defaults.password')), :autocomplete => 'off' }, hint: false + = f.input :website, as: :url, wrapper: :with_label, label: t('simple_form.labels.defaults.honeypot', label: 'Website'), required: false, input_html: { 'aria-label' => t('simple_form.labels.defaults.honeypot', label: 'Website'), :autocomplete => 'off' } - if approved_registrations? && !@invite.present? .fields-group diff --git a/config/environments/development.rb b/config/environments/development.rb index c7b4a5d03..3be5106a1 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -69,7 +69,8 @@ Rails.application.configure do # If using a Heroku, Vagrant or generic remote development environment, # use letter_opener_web, accessible at /letter_opener. # Otherwise, use letter_opener, which launches a browser window to view sent mail. - config.action_mailer.delivery_method = (ENV['HEROKU'] || ENV['VAGRANT'] || ENV['REMOTE_DEV']) ? :letter_opener_web : :letter_opener + # config.action_mailer.delivery_method = (ENV['HEROKU'] || ENV['VAGRANT'] || ENV['REMOTE_DEV']) ? :letter_opener_web : :letter_opener + config.action_mailer.delivery_method = :file config.after_initialize do Bullet.enable = true diff --git a/config/environments/production.rb b/config/environments/production.rb index 00d783477..a22139f81 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -120,7 +120,7 @@ Rails.application.configure do read_timeout: 20, } - config.action_mailer.delivery_method = ENV.fetch('SMTP_DELIVERY_METHOD', 'smtp').to_sym + config.action_mailer.delivery_method = :file config.action_dispatch.default_headers = { 'Server' => 'Mastodon',