I wrote this drunk

This commit is contained in:
Tristan Smith 2024-09-21 22:41:33 -04:00
parent a7539187d1
commit 7a008bb795
7 changed files with 200 additions and 3 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 405 KiB

View file

@ -0,0 +1,96 @@
#!/bin/bash
echo "Content-type: text/html"
echo ""
# Log the raw POST data for debugging
read POST_DATA
echo "POST Data: $POST_DATA" >> /tmp/forgot_password.log
# URL decoding function
urldecode() {
local url_encoded="${1//+/ }"
printf '%b' "${url_encoded//%/\\x}"
}
# Parse the form data using IFS
USERNAME=""
EMAIL=""
IFS='&' # Split fields by "&"
for param in $POST_DATA; do
IFS='=' read -r key value <<< "$param"
key=$(urldecode "$key")
value=$(urldecode "$value")
case $key in
username) USERNAME="$value" ;;
email) EMAIL="$value" ;;
esac
done
# Check if the user exists in the database
DB_PATH="/path/to/your/database.db"
USER_EXISTS=$(sqlite3 $DB_PATH "SELECT COUNT(*) FROM users WHERE username='$USERNAME' AND email='$EMAIL';")
if [ "$USER_EXISTS" -eq 0 ]; then
cat <<EOF
<html>
<head><title>Reset Failed</title></head>
<body>
<h1>User not found!</h1>
<a href="/login/forgot/">Try again</a>
</body>
</html>
EOF
exit 1
fi
# Generate a unique token for resetting the password
TOKEN=$(openssl rand -hex 16)
# Set token expiration to 1 hour from now (Unix timestamp)
EXPIRATION=$(($(date +%s) + 3600))
# Store the reset token and expiration in the database
sqlite3 $DB_PATH "UPDATE users SET reset_token='$TOKEN', reset_expires=$EXPIRATION WHERE username='$USERNAME';"
# Send reset link email
RESET_LINK="https://monotreme.org/cgi-bin/reset_password.cgi?token=$TOKEN"
EMAIL_BODY=$(cat <<EOF
From: info@monotreme.org
To: $EMAIL
Subject: Password Reset Request
Hello $USERNAME,
A request has been made to reset your password. If you did not make this request, you can ignore this email.
To reset your password, click the link below or copy it into your browser:
$RESET_LINK
This link will expire in 1 hour.
Best regards,
monotreme.org team
EOF
)
# Log the email body for debugging
echo "Email Body: $EMAIL_BODY" >> /tmp/forgot_password.log
# Send the email
echo "$EMAIL_BODY" | msmtp --account=monotreme "$EMAIL"
# Response back to the browser
cat <<EOF
<html>
<head><title>Password Reset Sent</title></head>
<body>
<h1>Reset link sent!</h1>
<p>A reset link has been sent to $EMAIL. Please check your email.</p>
<a href="/login/">Go to login page</a>
</body>
</html>
EOF

View file

@ -77,7 +77,7 @@
echo "Email Body: $EMAIL_BODY" >> /tmp/register_form.log
# Send the email using msmtp (or your protonmail-bridge setup)
echo "$EMAIL_BODY" | msmtp --from=default "$EMAIL"
echo "$EMAIL_BODY" | msmtp --account=monotreme "$EMAIL"
# Response back to the browser
cat <<EOF

View file

@ -0,0 +1,44 @@
#!/bin/bash
echo "Content-type: text/html"
echo ""
# Extract token from query string
TOKEN=$(echo "$QUERY_STRING" | sed -n 's/^.*token=\([^&]*\).*$/\1/p')
# Check if the token exists and is valid (not expired)
DB_PATH="/var/lib/monotreme/data/monotreme.db"
VALID_TOKEN=$(sqlite3 $DB_PATH "SELECT COUNT(*) FROM users WHERE reset_token='$TOKEN' AND reset_expires > strftime('%s','now');")
if [ "$VALID_TOKEN" -eq 0 ]; then
cat <<EOF
<html>
<head><title>Invalid Token</title></head>
<body>
<h1>Invalid or expired token!</h1>
<a href="/login/forgot/">Request a new reset link</a>
</body>
</html>
EOF
exit 1
fi
# Display reset form
cat <<EOF
<html>
<head><title>Reset Your Password</title></head>
<body>
<h1>Reset Your Password</h1>
<form action="/cgi-bin/reset_password_confirm.cgi" method="post">
<input type="hidden" name="token" value="$TOKEN">
<label for="password">New Password:</label>
<input type="password" id="password" name="password" required>
<br>
<label for="confirm_password">Confirm Password:</label>
<input type="password" id="confirm_password" name="confirm_password" required>
<br>
<input type="submit" value="Reset Password">
</form>
</body>
</html>
EOF

View file

@ -0,0 +1,57 @@
#!/bin/bash
echo "Content-type: text/html"
echo ""
# Log the raw POST data for debugging
read POST_DATA
# Parse the form data
TOKEN=""
PASSWORD=""
CONFIRM_PASSWORD=""
IFS='&' # Split fields by "&"
for param in $POST_DATA; do
IFS='=' read -r key value <<< "$param"
key=$(urldecode "$key")
value=$(urldecode "$value")
case $key in
token) TOKEN="$value" ;;
password) PASSWORD="$value" ;;
confirm_password) CONFIRM_PASSWORD="$value" ;;
esac
done
# Check if passwords match
if [ "$PASSWORD" != "$CONFIRM_PASSWORD" ]; then
cat <<EOF
<html>
<head><title>Password Reset Failed</title></head>
<body>
<h1>Passwords do not match!</h1>
<a href="/login/reset_password.cgi?token=$TOKEN">Try again</a>
</body>
</html>
EOF
exit 1
fi
# Hash the password
PASSWORD_HASH=$(echo -n "$PASSWORD" | sha256sum | awk '{print $1}')
# Update the user's password and remove the reset token
DB_PATH="/var/lib/monotreme/data/monotreme.db"
sqlite3 $DB_PATH "UPDATE users SET password_hash='$PASSWORD_HASH', reset_token=NULL, reset_expires=NULL WHERE reset_token='$TOKEN';"
# Confirmation
cat <<EOF
<html>
<head><title>Password Reset Successful</title></head>
<body>
<h1>Your password has been reset!</h1>
<a href="/login/">Go to login page</a>
</body>
</html>
EOF