I wrote this drunk
This commit is contained in:
parent
a7539187d1
commit
7a008bb795
7 changed files with 200 additions and 3 deletions
BIN
images/de39ed37-a629-4306-ba39-b538ecdd04d3.webp
Normal file
BIN
images/de39ed37-a629-4306-ba39-b538ecdd04d3.webp
Normal file
Binary file not shown.
After Width: | Height: | Size: 405 KiB |
96
scripts/forgot_password.cgi
Normal file
96
scripts/forgot_password.cgi
Normal 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
|
|
@ -77,7 +77,7 @@
|
||||||
echo "Email Body: $EMAIL_BODY" >> /tmp/register_form.log
|
echo "Email Body: $EMAIL_BODY" >> /tmp/register_form.log
|
||||||
|
|
||||||
# Send the email using msmtp (or your protonmail-bridge setup)
|
# 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
|
# Response back to the browser
|
||||||
cat <<EOF
|
cat <<EOF
|
||||||
|
|
44
scripts/reset_password.cgi
Normal file
44
scripts/reset_password.cgi
Normal 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
|
57
scripts/reset_password_confirm.cgi
Normal file
57
scripts/reset_password_confirm.cgi
Normal 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
|
Loading…
Reference in a new issue