diff --git a/app/controllers/settings/privacy_controller.rb b/app/controllers/settings/privacy_controller.rb
index 6deea58a..a4980d25 100644
--- a/app/controllers/settings/privacy_controller.rb
+++ b/app/controllers/settings/privacy_controller.rb
@@ -12,6 +12,7 @@ class Settings::PrivacyController < ApplicationController
:privacy_allow_stranger_answers,
:privacy_show_in_search,
:privacy_require_user,
+ :privacy_noindex,
:privacy_hide_social_graph)
if current_user.update(user_attributes)
flash[:success] = t(".success")
diff --git a/app/views/layouts/base.html.haml b/app/views/layouts/base.html.haml
index a0e37c09..e5a7748d 100644
--- a/app/views/layouts/base.html.haml
+++ b/app/views/layouts/base.html.haml
@@ -9,6 +9,8 @@
%meta{ name: 'theme-color', content: mobile_theme_color, media: '(max-width: 992px)' }
- else
%meta{ name: 'theme-color', content: theme_color }
+ - if @user&.privacy_noindex? || @answer&.user&.privacy_noindex? || @question&.user&.privacy_noindex?
+ %meta{ name: 'robots', content: 'noindex' }
%link{ rel: 'manifest', href: '/manifest.json', crossorigin: 'use-credentials' }
%link{ rel: 'apple-touch-icon', href: '/icons/maskable_icon_x192.png' }
%link{ rel: 'mask-icon', href: '/icons/icon.svg', color: theme_color }
diff --git a/app/views/settings/privacy/edit.html.haml b/app/views/settings/privacy/edit.html.haml
index f320c928..47d59b89 100644
--- a/app/views/settings/privacy/edit.html.haml
+++ b/app/views/settings/privacy/edit.html.haml
@@ -6,6 +6,7 @@
= f.check_box :privacy_require_user
= f.check_box :privacy_allow_public_timeline
= f.check_box :privacy_allow_stranger_answers
+ = f.check_box :privacy_noindex
= f.check_box :privacy_hide_social_graph
= f.primary
diff --git a/config/locales/activerecord.en.yml b/config/locales/activerecord.en.yml
index 2d619968..4377f979 100644
--- a/config/locales/activerecord.en.yml
+++ b/config/locales/activerecord.en.yml
@@ -72,6 +72,7 @@ en:
privacy_require_user: "Require users to be logged in to ask you questions"
privacy_allow_public_timeline: "Show your answers in the public timeline"
privacy_allow_stranger_answers: "Allow other people to answer your questions"
+ privacy_noindex: "Prevent search engines from indexing your profile"
privacy_hide_social_graph: "Hide your social graph from others"
profile_picture: "Profile picture"
profile_header: "Profile header"
diff --git a/db/migrate/20221116201723_add_privacy_noindex_to_user.rb b/db/migrate/20221116201723_add_privacy_noindex_to_user.rb
new file mode 100644
index 00000000..b04ada0d
--- /dev/null
+++ b/db/migrate/20221116201723_add_privacy_noindex_to_user.rb
@@ -0,0 +1,11 @@
+# frozen_string_literal: true
+
+class AddPrivacyNoindexToUser < ActiveRecord::Migration[6.1]
+ def up
+ add_column :users, :privacy_noindex, :boolean, default: false
+ end
+
+ def down
+ remove_column :users, :privacy_noindex
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 907abcfd..f871d86d 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema.define(version: 2022_11_15_194933) do
+ActiveRecord::Schema.define(version: 2022_11_16_201723) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@@ -295,6 +295,8 @@ ActiveRecord::Schema.define(version: 2022_11_15_194933) do
t.integer "otp_module", default: 0, null: false
t.boolean "privacy_lock_inbox", default: false
t.boolean "privacy_require_user", default: false
+ t.boolean "privacy_noindex", default: false
+ t.boolean "privacy_hide_social_graph", default: false
t.index ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true
t.index ["email"], name: "index_users_on_email", unique: true
t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
diff --git a/spec/controllers/answer_controller_spec.rb b/spec/controllers/answer_controller_spec.rb
index bca4b142..b2c39fd5 100644
--- a/spec/controllers/answer_controller_spec.rb
+++ b/spec/controllers/answer_controller_spec.rb
@@ -1,10 +1,14 @@
-require 'rails_helper'
+# frozen_string_literal: true
+
+require "rails_helper"
describe AnswerController do
- let(:user) { FactoryBot.create :user,
- otp_module: :disabled,
- otp_secret_key: 'AAAAAAAA'}
- let(:answer) { FactoryBot.create :answer, user: user }
+ let(:user) do
+ FactoryBot.create :user,
+ otp_module: :disabled,
+ otp_secret_key: "AAAAAAAA"
+ end
+ let(:answer) { FactoryBot.create :answer, user: }
describe "#show" do
subject { get :show, params: { username: user.screen_name, id: answer.id } }
@@ -18,5 +22,21 @@ describe AnswerController do
expect(response).to render_template("answer/show")
end
end
+
+ context "user opts out of search indexing" do
+ render_views
+
+ before(:each) do
+ sign_in user
+ user.privacy_noindex = true
+ user.save
+ end
+
+ it "renders the answer/show template" do
+ subject
+ expect(assigns(:answer)).to eq(answer)
+ expect(response.body).to include("")
+ end
+ end
end
end
diff --git a/spec/controllers/user_controller_spec.rb b/spec/controllers/user_controller_spec.rb
index b66b50b8..aa898073 100644
--- a/spec/controllers/user_controller_spec.rb
+++ b/spec/controllers/user_controller_spec.rb
@@ -47,6 +47,22 @@ describe UserController, type: :controller do
expect(response).to render_template("user/show")
end
end
+
+ context "user opts out of search indexing" do
+ render_views
+
+ before(:each) do
+ sign_in user
+ user.privacy_noindex = true
+ user.save
+ end
+
+ it "renders the answer/show template" do
+ subject
+ expect(assigns(:user)).to eq(user)
+ expect(response.body).to include("")
+ end
+ end
end
describe "#followers" do