Date: Sun, 17 Dec 2023 19:50:22 -0500
Subject: [PATCH 042/224] Reset password mod tool
---
app/controllers/mod_tools_controller.rb | 38 +++++++++++++
app/helpers/mod_tools_helper.rb | 2 +
app/views/mod_tools/_password_reset_form.erb | 21 +++++++
app/views/mod_tools/destroy_user.html.erb | 2 +
app/views/mod_tools/index.html.erb | 49 ++++++++++++++++
.../mod_tools/show_password_reset.html.erb | 54 ++++++++++++++++++
app/views/mod_tools/show_user.html.erb | 2 +
.../mod_tools/update_password_reset.html.erb | 2 +
config/routes.rb | 10 ++++
public/base.css | 56 ++++++++++++++++++-
test/controllers/mod_tools_controller_test.rb | 28 ++++++++++
11 files changed, 263 insertions(+), 1 deletion(-)
create mode 100644 app/controllers/mod_tools_controller.rb
create mode 100644 app/helpers/mod_tools_helper.rb
create mode 100644 app/views/mod_tools/_password_reset_form.erb
create mode 100644 app/views/mod_tools/destroy_user.html.erb
create mode 100644 app/views/mod_tools/index.html.erb
create mode 100644 app/views/mod_tools/show_password_reset.html.erb
create mode 100644 app/views/mod_tools/show_user.html.erb
create mode 100644 app/views/mod_tools/update_password_reset.html.erb
create mode 100644 test/controllers/mod_tools_controller_test.rb
diff --git a/app/controllers/mod_tools_controller.rb b/app/controllers/mod_tools_controller.rb
new file mode 100644
index 00000000..b2903bfa
--- /dev/null
+++ b/app/controllers/mod_tools_controller.rb
@@ -0,0 +1,38 @@
+class ModToolsController < ApplicationController
+ before_action :authorize_with_admin
+
+ def index
+ end
+
+ def show_password_reset
+ end
+
+ def update_password_reset
+ email = params.permit(:email)['email']
+
+ if !email || email.length < 6
+ return redirect_to mod_tools_passwords_index_path(fail: 'Email segment too short. Must be at least 6 letters. They need to provide more of their email.', email:)
+ end
+
+ # Prepared statement, rails escapes and wraps template var here.
+ matches = User.where('email LIKE ?', "%#{email}%").all
+
+ if matches.length > 1
+ return redirect_to mod_tools_passwords_index_path(fail: 'Matches more than 1 account, can they be more specific?', email:)
+ end
+
+ if !matches || matches.length == 0
+ return redirect_to mod_tools_passwords_index_path(fail: 'Email does not exist in database, did they make a typo?', email:)
+ end
+
+ matches[0].password_reset_token = SecureRandom.uuid
+ matches[0].save
+ redirect_to mod_tools_passwords_index_path(link: matches[0].password_reset_token, username: matches[0].username, email:)
+ end
+
+ def show_user
+ end
+
+ def destroy_user
+ end
+end
diff --git a/app/helpers/mod_tools_helper.rb b/app/helpers/mod_tools_helper.rb
new file mode 100644
index 00000000..631076ef
--- /dev/null
+++ b/app/helpers/mod_tools_helper.rb
@@ -0,0 +1,2 @@
+module ModToolsHelper
+end
diff --git a/app/views/mod_tools/_password_reset_form.erb b/app/views/mod_tools/_password_reset_form.erb
new file mode 100644
index 00000000..d8528242
--- /dev/null
+++ b/app/views/mod_tools/_password_reset_form.erb
@@ -0,0 +1,21 @@
+<%= turbo_frame_tag :mod_tools_password_reset_form do %>
+ <%= form_with url: mod_tools_passwords_update_path, method: :post do |f| %>
+ <%= f.label :email, 'Email address user claims is theirs:', style: "display: block" %>
+ <%= f.text_field :email, value: params['email'] %>
+ <%= f.submit 'Try to generate a reset link' %>
+ <% end %>
+
+ <% if params['fail'] || params['link'] %>
+
+ <% if params['fail'] %>
+ <%= params['fail'] %>
+ <% end %>
+
+ <% if params['link'] %>
+
+ Found 1 user, <%= params['username'] %>
+ https://walltaker.joi.how/i-forgor/commit/<%= params['link'] %>
+ <% end %>
+ <% end %>
+
+<% end %>
diff --git a/app/views/mod_tools/destroy_user.html.erb b/app/views/mod_tools/destroy_user.html.erb
new file mode 100644
index 00000000..deaa66f3
--- /dev/null
+++ b/app/views/mod_tools/destroy_user.html.erb
@@ -0,0 +1,2 @@
+ModTools#destroy_user
+Find me in app/views/mod_tools/destroy_user.html.erb
diff --git a/app/views/mod_tools/index.html.erb b/app/views/mod_tools/index.html.erb
new file mode 100644
index 00000000..da89036d
--- /dev/null
+++ b/app/views/mod_tools/index.html.erb
@@ -0,0 +1,49 @@
+
+
+
+
+ Read me
+
+
+ You can cause IRREVERSIBLE damage here. Both to the site, and our user's privacy. There are no
+ confirmations before you do an action. You need to think before you click.
+
+
+
+ We consider the following to be PII (Personally Identifiable Information):
+
+
+ - Email address
+ - IP Addresses
+ - Messages
+
+
+ This information should NEVER be provided to anyone. That includes,
+ NOT EVEN TELLING THE USER THEIR OWN PII INFO. Always assume someone's account is hacked and
+ that you are being manipulated. You may ONLY ask for THEM to provide it, and you
+ can confirm if it's correct or not. Provide no more information.
+
+
+
+ If you fuck up with tools I provide to you on this panel, you will lose all access. - Gray
+
+
+
+
+
+ Mod Tools
+ Gray trusts you. The highlighted button in each category is the most useful.
+
+
+
+ Authentication Issues
+ <%= button_to "They forgot their password", mod_tools_passwords_index_path, method: :get %>
+ <%= button_to "They can't log in but know their password", mod_tools_passwords_index_path, method: :get, class: 'secondary' %>
+
+
+
+ Moderation
+ <%= button_to "I need to ban a user with an account", mod_tools_passwords_index_path, method: :get %>
+ <%= button_to "I suspect a user is sending bad messages", mod_tools_passwords_index_path, method: :get, class: 'secondary' %>
+ <%= button_to "I need to ban an anon IP address", mod_tools_passwords_index_path, method: :get, class: 'secondary' %>
+
\ No newline at end of file
diff --git a/app/views/mod_tools/show_password_reset.html.erb b/app/views/mod_tools/show_password_reset.html.erb
new file mode 100644
index 00000000..e78054e4
--- /dev/null
+++ b/app/views/mod_tools/show_password_reset.html.erb
@@ -0,0 +1,54 @@
+
+
+
+
+ Reset Any Account's Password
+ Gray trusts you. Remember our PII rules.
+
+
+Step 1: Get proof
+
+ Ask something like the following: "Can you give me all or part of the email you used to make the account? I only need this to confirm this is really you." A partial email is alright, as long as it contains something on the left side of the @ symbol. If they say "it was a gmail.com address", this does not count.
+
+
+
+
+
+
+ Be vigilant.
+
+
If they refuse, or say they forgot entirely, you cannot reset their password. Simply refuse, explain that it's required, and end the DM. They may be manipulating you to get access to the account. This has happened before.
+
+
If they used an email hiding service, that's not an excuse for not remembering it.
+
+
+Step 2: Check proof and generate link
+
+ Enter their response below. This does a check thru the user's table, looking for an email similar to the entered value. Capitalization is ignored, but it must be one whole chunk of the email address. ("gray@gmail.com" will match "pupgray@gmail.com", but NOT "pupg@gmail.com")
+
+
+
+
+
+
+ Be vigilant.
+
+
Be somewhat flexible if it's obvious they made a typo, but if there is no results, and they are sure that their email is that, end the DM. Give maybe 2 chances to try different ones.
+
+
If they used an email hiding service, that's not an excuse for not remembering it.
+
+
+<%= render 'mod_tools/password_reset_form' %>
+
+Step 3: If successful, give them the link
+
+ Verify that you got a green checkbox in step 2, and that the user name that showed up matches what it should be for this user. If yes, you may give them the password reset link from step 2.
+
+
+
+ If you got a red cross, this means no account was found. Use your best judgement about if user should be asked again. Remember, anyone could be trying to get into an account.
+
\ No newline at end of file
diff --git a/app/views/mod_tools/show_user.html.erb b/app/views/mod_tools/show_user.html.erb
new file mode 100644
index 00000000..91b20080
--- /dev/null
+++ b/app/views/mod_tools/show_user.html.erb
@@ -0,0 +1,2 @@
+ModTools#show_user
+Find me in app/views/mod_tools/show_user.html.erb
diff --git a/app/views/mod_tools/update_password_reset.html.erb b/app/views/mod_tools/update_password_reset.html.erb
new file mode 100644
index 00000000..c13f0065
--- /dev/null
+++ b/app/views/mod_tools/update_password_reset.html.erb
@@ -0,0 +1,2 @@
+ModTools#update_password_reset
+Find me in app/views/mod_tools/update_password_reset.html.erb
diff --git a/config/routes.rb b/config/routes.rb
index 9e970628..15bff0a3 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -65,4 +65,14 @@
resources :comments
end
mount Blazer::Engine, at: "blazer"
+
+ scope path: :mod_tools, as: 'mod_tools' do
+ get '/', to: 'mod_tools#index', as: 'index'
+
+ scope path: :passwords, as:'passwords' do
+ get '/', to: 'mod_tools#show_password_reset', as: 'index'
+ post 'update', to: 'mod_tools#update_password_reset', as: 'update'
+ end
+ get :user, to: 'mod_tools#show_user'
+ end
end
diff --git a/public/base.css b/public/base.css
index 284fc230..af7c7220 100644
--- a/public/base.css
+++ b/public/base.css
@@ -241,7 +241,7 @@ h2 ion-icon {
font-size: 0.8em;
}
-h2 ion-icon.big {
+ion-icon.big {
transform: translateY(0.15em);
font-size: 1em;
}
@@ -681,6 +681,28 @@ a.small:hover {
position: relative;
}
+.accent-block > .scare-charm {
+ position: absolute;
+ bottom: 10px;
+ right: 10px;
+ font-size: 110px;
+ mix-blend-mode: multiply;
+ color: #c2c2c2;
+ opacity: 0.75;
+}
+
+.accent-block--warning {
+ background-image: linear-gradient(45deg, #ffb300 25%, #d0a536 25%, #d0a536 50%, #ffb300 50%, #ffb300 75%, #d0a536 75%, #d0a536 100%);
+ background-size: 56.57px 56.57px;
+ color: #212121;
+ text-shadow: 0 0 2px #ffb300;
+ font-weight: bold;
+}
+
+.accent-block--warning strong, .accent-block--warning .accent-block__charm {
+ color: inherit;
+}
+
.accent-block > p {
margin: 0;
}
@@ -1243,3 +1265,35 @@ section .then {
gap: 1rem;
}
}
+
+.mod_tool__result {
+ padding: 1rem;
+ text-align: center;
+ font-size: 1.2rem;
+}
+
+.mod_tool__result--success::before {
+ content: '';
+ display: block;
+ height: 2px;
+ width: 100%;
+ background: var(--success);
+ margin-bottom: 1rem;
+}
+
+.mod_tool__result--fail::before {
+ content: '';
+ display: block;
+ height: 2px;
+ width: 100%;
+ background: var(--danger);
+ margin-bottom: 1rem;
+}
+
+.mod_tool__result--success ion-icon {
+ color: var(--success);
+}
+
+.mod_tool__result--fail ion-icon {
+ color: var(--danger);
+}
\ No newline at end of file
diff --git a/test/controllers/mod_tools_controller_test.rb b/test/controllers/mod_tools_controller_test.rb
new file mode 100644
index 00000000..0cd4d18b
--- /dev/null
+++ b/test/controllers/mod_tools_controller_test.rb
@@ -0,0 +1,28 @@
+require "test_helper"
+
+class ModToolsControllerTest < ActionDispatch::IntegrationTest
+ test "should get index" do
+ get mod_tools_index_url
+ assert_response :success
+ end
+
+ test "should get show_password_reset" do
+ get mod_tools_show_password_reset_url
+ assert_response :success
+ end
+
+ test "should get update_password_reset" do
+ get mod_tools_update_password_reset_url
+ assert_response :success
+ end
+
+ test "should get show_user" do
+ get mod_tools_show_user_url
+ assert_response :success
+ end
+
+ test "should get destroy_user" do
+ get mod_tools_destroy_user_url
+ assert_response :success
+ end
+end
From 92a207f3840952bd3b09fa9da62c20a354f59209 Mon Sep 17 00:00:00 2001
From: Pup Gray
Date: Sun, 17 Dec 2023 20:00:36 -0500
Subject: [PATCH 043/224] More powerful password reset mod tool, you can search
tiny strings
---
app/controllers/mod_tools_controller.rb | 11 ++++++++---
app/views/mod_tools/_password_reset_form.erb | 2 +-
app/views/mod_tools/index.html.erb | 14 ++++++++------
app/views/mod_tools/show_password_reset.html.erb | 2 +-
4 files changed, 18 insertions(+), 11 deletions(-)
diff --git a/app/controllers/mod_tools_controller.rb b/app/controllers/mod_tools_controller.rb
index b2903bfa..48b7803f 100644
--- a/app/controllers/mod_tools_controller.rb
+++ b/app/controllers/mod_tools_controller.rb
@@ -10,12 +10,12 @@ def show_password_reset
def update_password_reset
email = params.permit(:email)['email']
- if !email || email.length < 6
+ if !email || email.length < 2
return redirect_to mod_tools_passwords_index_path(fail: 'Email segment too short. Must be at least 6 letters. They need to provide more of their email.', email:)
end
# Prepared statement, rails escapes and wraps template var here.
- matches = User.where('email LIKE ?', "%#{email}%").all
+ matches = User.where('lower(email) LIKE ?', "%#{email.downcase}%").all
if matches.length > 1
return redirect_to mod_tools_passwords_index_path(fail: 'Matches more than 1 account, can they be more specific?', email:)
@@ -27,7 +27,12 @@ def update_password_reset
matches[0].password_reset_token = SecureRandom.uuid
matches[0].save
- redirect_to mod_tools_passwords_index_path(link: matches[0].password_reset_token, username: matches[0].username, email:)
+
+ if email.length < 6
+ return redirect_to mod_tools_passwords_index_path(link: matches[0].password_reset_token, username: matches[0].username, fail: "Search provided was short. (Only #{email.length} letters!) Are you sure you aren\'t being manipulated? Someone may be able to guess a small portion of an email.", email: matches[0].email)
+ end
+
+ redirect_to mod_tools_passwords_index_path(link: matches[0].password_reset_token, username: matches[0].username, email: matches[0].email)
end
def show_user
diff --git a/app/views/mod_tools/_password_reset_form.erb b/app/views/mod_tools/_password_reset_form.erb
index d8528242..6e609870 100644
--- a/app/views/mod_tools/_password_reset_form.erb
+++ b/app/views/mod_tools/_password_reset_form.erb
@@ -8,7 +8,7 @@
<% if params['fail'] || params['link'] %>