release first implementation

This commit is contained in:
Evan N 2025-02-22 20:09:07 -06:00
parent fd357494e5
commit b69170a200
11 changed files with 668 additions and 35 deletions

View File

@ -1,9 +1,48 @@
from db import * from db import *
from sendmail import *
import bcrypt
class accounts: class accounts:
def hash_password(password):
salt = bcrypt.gensalt()
hashed_password = bcrypt.hashpw(password.encode('utf-8'), salt)
return hashed_password
def register(email, password): def register(email, password):
if (db.add_account(email, password)): if (db.add_account(email, accounts.hash_password(password))):
print("Registered " + str(email) + " with password " + str(password))
return True return True
def authenticate_account(email, password): def authenticate_account(email, password): # Authenticate account with password
pass pass
def check_password(stored_hash, input_password):
# Check if the entered password matches the stored hashed password
return bcrypt.checkpw(input_password.encode('utf-8'), stored_hash)
# Verify the password
is_correct = check_password(hashed_password, "my_secure_password")
if is_correct:
print("Password is correct!")
else:
print("Invalid password.")
def create_account_otp(email):
if db.account_exists(email):
otp = mail.gen_code()
if db.account_add_otp(email, otp):
mail.send(email, otp)
return True
else:
return False
else:
return False
def authenticate_account_otp(email, otp): # Authenticate account without password
if (db.check_account_otp(email)):
if (int(otp) == int(db.get_account_otp(email))):
db.account_del_otp(email)
return True
elif (not db.check_account_otp(email)):
db.account_del_otp(email)
return False

View File

@ -1,4 +1,4 @@
from http.server import BaseHTTPRequestHandler, HTTPServer from http.server import BaseHTTPRequestHandler, HTTPServer, SimpleHTTPRequestHandler
from socket import * from socket import *
from sendmail import mail from sendmail import mail
from verification import otp from verification import otp
@ -6,14 +6,19 @@ from db import *
from accounts import * from accounts import *
from urllib.parse import urlparse, parse_qs from urllib.parse import urlparse, parse_qs
import os.path import os.path
import ssl
import re
class MyRequestHandler(BaseHTTPRequestHandler): class MyRequestHandler(SimpleHTTPRequestHandler):
base_path = "/home/arcodeskel/Desktop/Verification Platt Discord/" base_path = "/home/arcodeskel/Desktop/Verification Platt Discord/"
def log_message(self, format, *args):
return
def do_GET(self): def do_GET(self):
requested_path = os.path.join(self.base_path, "pages", "index.php") requested_path = os.path.join(self.base_path, "pages", "index.html")
if not os.path.abspath(requested_path).startswith(os.path.abspath(self.base_path)): if not os.path.abspath(requested_path).startswith(os.path.abspath(self.base_path)):
self.send_response(403) self.send_response(403)
@ -43,15 +48,45 @@ class MyRequestHandler(BaseHTTPRequestHandler):
if (data_input.startswith("email=")): if (data_input.startswith("email=")):
email = parsed_data.get('email', [None])[0] # defaults to none if email is not found email = parsed_data.get('email', [None])[0] # defaults to none if email is not found
requested_path = os.path.join(self.base_path, "pages", "exists.html")
if (db.account_exists(email)):
with open(requested_path, 'r') as file:
file_to_open = file.read()
self.send_response(200)
self.end_headers()
self.wfile.write(bytes(file_to_open, 'utf-8'))
return
password = parsed_data.get('passwd', [None])[0] password = parsed_data.get('passwd', [None])[0]
code = mail.gen_code() code = mail.gen_code()
emailRegex = r'^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,6}$'
passwordRegex = r'^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$'
if (email != None and password != None and str(email).endswith("@uwplatt.edu") and re.match(emailRegex, email) and re.match(passwordRegex, password)):
db.add_session(email, password, code) db.add_session(email, password, code)
mail.send(email, code) if (mail.send(email, code) == False):
requested_path = os.path.join(self.base_path, "pages", "fail.html")
with open(requested_path, 'r') as file:
file_to_open = file.read()
self.send_response(200)
self.end_headers()
self.wfile.write(bytes(file_to_open, 'utf-8'))
else:
requested_path = os.path.join(self.base_path, "pages", "fail.html")
with open(requested_path, 'r') as file:
file_to_open = file.read()
self.send_response(200)
self.end_headers()
self.wfile.write(bytes(file_to_open, 'utf-8'))
return
requested_path = os.path.join(self.base_path, "pages", "otp.php")
requested_path = os.path.join(self.base_path, "pages", "otp.html")
if not os.path.abspath(requested_path).startswith(os.path.abspath(self.base_path)): if not os.path.abspath(requested_path).startswith(os.path.abspath(self.base_path)):
self.send_response(403) self.send_response(403)
@ -104,7 +139,7 @@ class MyRequestHandler(BaseHTTPRequestHandler):
else: else:
db.del_session(email) db.del_session(email)
requested_path = os.path.join(self.base_path, "pages", "success.html") requested_path = os.path.join(self.base_path, "pages", "fail.html")
if not os.path.abspath(requested_path).startswith(os.path.abspath(self.base_path)): if not os.path.abspath(requested_path).startswith(os.path.abspath(self.base_path)):
self.send_response(403) self.send_response(403)
self.end_headers() self.end_headers()
@ -124,7 +159,7 @@ class MyRequestHandler(BaseHTTPRequestHandler):
self.wfile.write(bytes(file_to_open, 'utf-8')) self.wfile.write(bytes(file_to_open, 'utf-8'))
else: else:
db.del_session(email) db.del_session(email)
requested_path = os.path.join(self.base_path, "pages", "success.html") requested_path = os.path.join(self.base_path, "pages", "fail.html")
if not os.path.abspath(requested_path).startswith(os.path.abspath(self.base_path)): if not os.path.abspath(requested_path).startswith(os.path.abspath(self.base_path)):
self.send_response(403) self.send_response(403)
self.end_headers() self.end_headers()
@ -143,17 +178,17 @@ class MyRequestHandler(BaseHTTPRequestHandler):
self.end_headers() self.end_headers()
self.wfile.write(bytes(file_to_open, 'utf-8')) self.wfile.write(bytes(file_to_open, 'utf-8'))
Handler = MyRequestHandler
if (db.init()): if (db.init()):
pass pass
else: else:
print("Init returned false, there might be an issue!") print("Db did not return True. Something went very wrong!")
hostName = "localhost" Handler = MyRequestHandler
serverPort = 8080
server = HTTPServer((hostName, serverPort), Handler) context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
context.load_cert_chain(certfile='./certs/cert.pem', keyfile='./certs/key.pem')
context.check_hostname = False
server.serve_forever() with HTTPServer(("0.0.0.0", 4443), MyRequestHandler) as httpd:
#httpd.socket = context.wrap_socket(httpd.socket, server_side=True)
httpd.serve_forever()

135
db.py
View File

@ -7,7 +7,7 @@ class db:
conn = sqlite3.connect('accounts.db') conn = sqlite3.connect('accounts.db')
cursor = conn.cursor() cursor = conn.cursor()
cursor.execute('''CREATE TABLE IF NOT EXISTS sessions (email text UNIQUE, password integer, code integer, datedel text)''') cursor.execute('''CREATE TABLE IF NOT EXISTS sessions (email text UNIQUE, password integer, code integer, datedel text)''')
cursor.execute('''CREATE TABLE IF NOT EXISTS accounts (email text UNIQUE, password integer)''') cursor.execute('''CREATE TABLE IF NOT EXISTS accounts (email text UNIQUE, password integer, discord text UNIQUE, mc text UNIQUE, code integer, datedel text)''')
conn.commit() conn.commit()
conn.close() conn.close()
return True return True
@ -90,3 +90,136 @@ class db:
conn.commit() conn.commit()
conn.close() conn.close()
return True return True
def account_exists(email):
conn = sqlite3.connect('accounts.db')
cursor = conn.cursor()
match_sql = '''SELECT email FROM accounts WHERE email = ? LIMIT 1'''
cursor.execute(match_sql, (email, ))
fetch_acc = cursor.fetchone()
if fetch_acc is None or False:
return False
conn.close()
return True
def account_add_otp(email, otp):
conn = sqlite3.connect('accounts.db')
cursor = conn.cursor()
insert_code = "UPDATE accounts SET code = ? WHERE email = ?"
insert_datedel = "UPDATE accounts SET datedel = ? WHERE email = ?"
cursor.execute(insert_code, (otp, email, ))
cursor.execute(insert_datedel, (datetime.now() + timedelta(minutes=5), email, ))
conn.commit()
conn.close()
return True
def account_del_otp(email):
conn = sqlite3.connect('accounts.db')
cursor = conn.cursor()
empty = None
remove_code = "UPDATE sessions SET code = ? WHERE email = ?"
remove_datedel = "UPDATE sessions SET datedel = ? WHERE email = ?"
cursor.execute(remove_code, (empty, email, ))
cursor.execute(remove_datedel, (empty, email, ))
conn.commit()
conn.close()
return True
def check_account_otp(email):
conn = sqlite3.connect('accounts.db')
cursor = conn.cursor()
past_sql = '''SELECT datedel FROM accounts WHERE email = ? LIMIT 1'''
cursor.execute(past_sql, (email, ))
fetch_past = cursor.fetchone()
past = fetch_past[0]
if (past is None or False):
return False
present = datetime.now()
conn.close()
if (str(present) > past):
db.account_del_otp(email)
return False
else:
return True
def get_account_otp(email):
conn = sqlite3.connect('accounts.db')
cursor = conn.cursor()
getotp = '''SELECT code FROM accounts WHERE email = ?'''
cursor.execute(getotp, (email, ))
fetch_code = cursor.fetchone()
code = fetch_code[0]
if (code is None or False):
return False
else:
return code
def discord_exists(email):
conn = sqlite3.connect('accounts.db')
cursor = conn.cursor()
get_discord = '''SELECT discord FROM accounts WHERE email = ?'''
cursor.execute(get_discord, (email, ))
fetch_discord = cursor.fetchone()
if (fetch_discord == None):
return False
discord = fetch_discord[0]
if (discord == None):
return False
return discord
def add_discord(discord, email):
conn = sqlite3.connect('accounts.db')
cursor = conn.cursor()
update_discord = '''UPDATE accounts SET discord = ? WHERE email = ?'''
cursor.execute(update_discord, (discord, email))
conn.commit()
conn.close()
return True
def add_mc(mc, email):
conn = sqlite3.connect('accounts.db')
cursor = conn.cursor()
add = "UPDATE accounts SET mc = ? WHERE email = ?"
cursor.execute(add, (mc, email, ))
conn.commit()
conn.close()
return True
def replace_mc(new, email):
conn = sqlite3.connect('accounts.db')
cursor = conn.cursor()
replace_name = "UPDATE accounts SET mc = ? WHERE email = ?"
cursor.execute(replace_name, (new, email, ))
conn.commit()
conn.close()
return True
def mc_email_lookup(mc):
conn = sqlite3.connect('accounts.db')
cursor = conn.cursor()
get_mc = '''SELECT email FROM accounts WHERE mc = ?'''
cursor.execute(get_mc, (mc, ))
fetch_mc = cursor.fetchone()
if (fetch_mc == None):
return False
email = fetch_mc[0]
return email
def mc_username_lookup(email):
conn = sqlite3.connect('accounts.db')
cursor = conn.cursor()
get_email = '''SELECT mc FROM accounts WHERE email = ?'''
cursor.execute(get_email, (email, ))
fetch_email = cursor.fetchone()
if (fetch_email == None):
return False
mc = fetch_email[0]
if (mc == None):
return False
return mc

120
discordbot.py Normal file
View File

@ -0,0 +1,120 @@
import discord
from discord.ext import commands
from discord.ext.commands import context
from discord import ui
from mctools import RCONClient
from db import *
from accounts import *
intents = discord.Intents.default()
intents.message_content = True
TOKEN = ''
MY_GUILD = discord.Object(id=)
bot = commands.Bot(command_prefix='$',intents=intents)
intents.messages = True
class check_details(ui.Modal, title="Update/Register Profile Information:"):
def __init__(self, email: str, code: int):
self.email = email
self.otpcode = code
self.mcname_by_email = db.mc_username_lookup(self.email) # NOT for use outside of the self.mcname placeholder
self.placeholder_mc = None # NOT for use outside of the self.mcname placeholder
if (self.mcname_by_email is not False or None):
self.placeholder_mc = self.mcname_by_email
self.otp = ui.TextInput(label=f"OTP Code sent to {self.email}", style=discord.TextStyle.short, required=True, min_length=4, max_length=4, placeholder="eg 0000")
self.mcname = ui.TextInput(label="Minecraft Username (optional)", style=discord.TextStyle.short, required=False, default=self.placeholder_mc)
super().__init__()
self.add_item(self.otp)
self.add_item(self.mcname)
self.custom_id = f"check_details_modal_{self.email}"
async def on_submit(self, interaction: discord.Interaction):
if (accounts.authenticate_account_otp(self.email, self.otp.value)):
if (self.email.endswith("@uwplatt.edu")):
member = interaction.user
role = discord.utils.get(interaction.guild.roles, name="pioneer")
await member.add_roles(role)
host = ""
port = 0000
password = ""
rcon = RCONClient(host, port)
if (db.mc_username_lookup(self.email) != self.mcname.value and db.mc_username_lookup(self.email) != False and db.mc_email_lookup(self.mcname.value) == False):
if rcon.login(password):
old = db.mc_username_lookup(self.email)
if (old is not False):
rcon.command(f"rank {old} guest")
db.add_mc(self.mcname.value, self.email)
rcon.command(f"rank {self.mcname.value} member")
await interaction.response.send_message(f"Profile updated! Email: {self.email}, New/Unchanged MC Username: {self.mcname}")
else:
await interaction.response.send_message("An error occured in deleting the old mc! The account may not be properly registered. Contact an administrator for guidance.")
return
elif (db.mc_email_lookup(self.mcname.value) == False or db.mc_username_lookup(self.email) == False):
if rcon.login(password):
db.add_mc(self.mcname.value, self.email)
rcon.command(f"rank {self.mcname.value} member")
await interaction.response.send_message(f"Profile updated! Email: {self.email}, MC Username: {self.mcname}")
elif (db.mc_email_lookup(self.mcname.value) != self.email):
self.mcname = "Mc name not added/changed due to being taken under a different email. Please contact the administrator if you beleive this was in error."
await interaction.response.send_message(f"Profile updated! Email: {self.email}, MC Username: {self.mcname}")
elif (db.mc_email_lookup(self.mcname.value) is False):
self.mcname = "N/A (user did not specify)"
await interaction.response.send_message(f"Profile updated! Email: {self.email}, MC Username: {self.mcname}")
else:
self.mcname = "An unknown error occured. Try again later."
await interaction.response.send_message(f"Profile updated! Email: {self.email}, MC Username: {self.mcname}")
else:
await interaction.response.send_message("An error occured. Try again or contact the administrator.")
return True
@bot.event
async def on_ready():
print('Logged on as', bot.user)
await bot.tree.sync(guild=MY_GUILD)
@bot.tree.command(name="login", description="login to account", guild=MY_GUILD)
async def login(interaction: discord.Interaction, email: str):
db.init()
member = interaction.user
if (interaction.channel.id != 0):
await interaction.channel.send("This command can only be used in the bot-cmds channel.")
return
if (db.discord_exists(email) is False):
if (db.add_discord(member.id, email)):
if (accounts.create_account_otp(email)):
otpcode = db.get_account_otp(email)
modal = check_details(email=email, code=otpcode)
await interaction.response.send_modal(modal)
else:
await interaction.channel.send(f"Account {email} does not appear to exist! To register, go to https://www.register.uwplattmc.com")
return
elif (int(member.id) == int(db.discord_exists((email)))):
if (accounts.create_account_otp(email)):
otpcode = db.get_account_otp(email)
modal = check_details(email=email, code=otpcode)
await interaction.response.send_modal(modal)
else:
await interaction.channel.send(f"Account {email} does not appear to exist! To register, go to https://www.register.uwplattmc.com")
return
else:
await interaction.channel.send("Only the registered discord account holder may make changes. Contact an if you beleive this is a mistake.")
return
bot.run(TOKEN)

22
pages/exists.html Normal file
View File

@ -0,0 +1,22 @@
<!DOCTYPE html>
<html lang="">
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<header></header>
<main>
<center>
<div style="position: relative; top: 10vw">
<img width="200" height="200" src="https://static.vecteezy.com/system/resources/previews/017/178/222/non_2x/round-cross-mark-symbol-with-transparent-background-free-png.png">
<h1>This account already exists</h1>
Contact an administrator if you belive this is a mistake
<p>Click <a href="http://www.register.uwplattmc.com">here</a> to retry</p>
</div>
</center>
</main>
<footer></footer>
</body>
</html>

View File

@ -7,11 +7,14 @@
<body> <body>
<header></header> <header></header>
<main> <main>
<center>
<div style="position: relative; top: 10vw">
<img width="200" height="200" src="https://static.vecteezy.com/system/resources/previews/017/178/222/non_2x/round-cross-mark-symbol-with-transparent-background-free-png.png">
<h1>Account has failed registration</h1> <h1>Account has failed registration</h1>
<p>This could be due to an incorrect email or an invalid/expired code. Contact site admin Evan for any difficulties.</p> <p>This could be due to an incorrect email or an invalid/expired code. Contact an admin for support.</p>
<p>Click <a>here</a> to retry</p> <p>Click <a href="http://www.register.uwplattmc.com">here</a> to retry</p>
</div>
</center>
</main> </main>
<footer></footer> <footer></footer>
</body> </body>

231
pages/index.html Normal file
View File

@ -0,0 +1,231 @@
<!DOCTYPE html>
<html lang="">
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<header></header>
<main>
<div class="content" id="js-content">
<h1>UWP Community Registration Portal</h1>
<p style="font-size: 12px; position: relative; bottom: 30px">Created by: Evan Niederwerfer at UW-Platteville</p>
<form method="post" action="otp.html">
<center>
<div style="display: block;">
<label for="email">Email:</label>
<input type="email" name="email" id="email" style="width: 350px;" onchange="check_email();">
<p class="valid-email" id="valid">Email meets all requirements</p>
<p class="not-email" id="notvalid">Email must be of valid format and end in @uwplatt.edu</p>
<p id="email_empty" style="color:red; font-size: 14px; margin-right: 310px;"></p>
</div>
<div style="display: block; position: relative; left:4.5%;">
<div>
<label for="passwd" class="passwd-label">Password:</label>
<input type="password" name="passwd" id="password" onchange="check_password();">
<input type="checkbox" name = "passwd_label" class="input-passwd" onclick="PasswdToggle()">
<label for="passwd_label" style="font-size: 13px;">Show Password</label>
<p class="valid-password" id="valid-password">*Password meets all requirements</p>
<p class="not-password" id="notvalid-password">*Password must contain 1 uppercase letter, 1 lowercase letter, 1 digit (0-9), 1 special character (only @$!%*?&), minimum length 8 characters</p>
<p id="password_empty" style="color:red; font-size: 14px; margin-right: 410px;"></p>
</div>
</center>
<button type="submit">Register Account</button>
</form>
</div>
</main>
<footer></footer>
</body>
<style>
body {
overflow-x: hidden;
}
#js-content {
display: none;
}
.content {
position: relative;
text-align: center;
top: 10vh;
font-size: 30px;
}
a {
font-size: 15px;
position: relative;
top: 20px;
display: block;
}
input {
text-align: center;
}
.content h1 {
color: orange;
}
input {
padding: 5px;
width: 300px;
}
.valid-email {
color: green;
display: none;
font-size: 14px;
}
.not-email {
color: red;
display: none;
font-size: 14px;
}
.valid-password {
color: green;
display: none;
font-size: 14px;
}
.not-password {
color: red;
display: none;
font-size: 14px;
}
input {
border-radius: 20px;
border: blue 3px solid;
}
button {
padding: 20px;
width: 400px;
border-radius: 20px;
border: none;
background-color: #5aaa6d;
color: white;
font-size: 18px;
cursor: pointer;
}
.input-passwd {
width: 10px;
}
</style>
<script>
function check_email() {
let email = document.getElementById("email").value;
let valid = document.getElementById("valid");
let not_valid = document.getElementById("notvalid");
const emailRegex = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,6}$/;
if (String(email).endsWith("@uwplatt.edu") && emailRegex.test(email)) {
not_valid.style.display = "none";
valid.style.display = "block";
}
else {
not_valid.style.display = "block";
valid.style.display = "none";
}
};
function check_password() {
let password = document.getElementById("password").value;
let valid = document.getElementById("valid-password");
let not_valid = document.getElementById("notvalid-password");
const passwordRegex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$/;
if (passwordRegex.test(password)) {
not_valid.style.display = "none";
valid.style.display = "block";
}
else {
not_valid.style.display = "block";
valid.style.display = "none";
}
};
window.onload = function() {
document.getElementById("email").value = "";
document.getElementById("password").value = "";
document.getElementById('js-content').style.display = 'block';
checkTextbox1();
checkTextbox2();
};
const textbox1 = document.getElementById("email");
const textbox2 = document.getElementById("password");
const empty1 = document.getElementById("email_empty");
const empty2 = document.getElementById("password_empty");
function checkTextbox1() {
if (textbox1.value.trim() === "") {
empty1.textContent = "*Email cannot be empty";
} else if (textbox1.value.trim() != ""){
empty1.textContent = " ";
}
}
function checkTextbox2() {
if (textbox2.value.trim() === "") {
empty2.textContent = "*Password cannot be empty";
} else if (textbox2.value.trim() != "") {
empty2.textContent = " ";
}
}
function PasswdToggle() {
var x = document.getElementById("password");
if (x.type === "password") {
x.type = "text";
} else {
x.type = "password";
}
}
textbox1.addEventListener("input", checkTextbox1);
textbox2.addEventListener("input", checkTextbox2);
</script>
<noscript>
<div style="color: red; font-weight: bold;">
JavaScript is required to view this website properly. Please enable JavaScript in your browser settings.
</div>
</noscript>
</html>

44
pages/otp.html Normal file
View File

@ -0,0 +1,44 @@
<!DOCTYPE html>
<html lang="">
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<header></header>
<main>
<div style="position: relative; top: 10vw">
<form method="post">
<center>
<img width="300" height="200" src="https://static.vecteezy.com/system/resources/previews/022/719/488/non_2x/verification-otp-one-time-password-has-been-send-input-code-concept-illustration-flat-design-eps10-modern-graphic-element-for-landing-page-empty-state-ui-infographic-icon-vector.jpg">
<h1>Verification sent to <!-- PREFILL_EMAIL --></h1>
<p>Your code expires in 5 minutes. Click <a href="https://www.register.uwplattmc.com">here</a> to resend.</p>
<input type="hidden" name="verifEmail" id="email" value="<!-- PREFILL_EMAIL -->">
<label for="email">OTP Code (4 digits, 0000):</label>
<input type="number" name="verifOtp" id="otp">
<button type="submit">Submit</button>
<br>
<br>
</center>
</form>
<style>
button {
padding: 10px;
border-radius: 20px;
border: none;
background-color: #5aaa6d;
color: white;
font-size: 15px;
cursor: pointer;
}
</style>
</div>
</main>
</center>
<footer></footer>
</body>
</html>

View File

@ -8,8 +8,13 @@
<header></header> <header></header>
<main> <main>
<center>
<div style="position: relative; top: 10vw">
<img width="200" height="200" src="https://cdn.pixabay.com/photo/2017/03/28/01/46/check-mark-2180770_960_720.png">
<h1>Account was successfully registered</h1> <h1>Account was successfully registered</h1>
<p>Click <a>here</a> to go to the login page</p> <p>Please see the discord for more guidance</p>
</div>
</center>
</main> </main>
<footer></footer> <footer></footer>

View File

@ -18,20 +18,20 @@ class mail:
def send(email, code): def send(email, code):
try: try:
smtpObj = smtplib.SMTP_SSL('mail.example.com', 465) smtpObj = smtplib.SMTP_SSL('', 465)
# Identify yourself to an ESMTP server using EHLO # Identify yourself to an ESMTP server using EHLO
smtpObj.ehlo() smtpObj.ehlo()
# Login to the server (if required) # Login to the server (if required)
smtpObj.login('email', 'password') smtpObj.login('', '')
# Send an email # Send an email
msg = EmailMessage() msg = EmailMessage()
msg.set_content(f'You have requested a verification code. Your code is {code}. This code expires in 5 minutes.') msg.set_content(f'You have requested a verification code. Your code is {code}. This code expires in 5 minutes.')
msg['Subject'] = 'UWP Community Verification Code' msg['Subject'] = 'Community Verification Code'
msg['From'] = "email@example.com" msg['From'] = ""
msg['To'] = email msg['To'] = email
smtpObj.send_message(msg) smtpObj.send_message(msg)
@ -39,7 +39,7 @@ class mail:
# Quit the SMTP session # Quit the SMTP session
smtpObj.quit() smtpObj.quit()
except SMTPResponseException as e: except SMTPResponseException as e:
print(e) return False

1
sessions_remove.py Normal file
View File

@ -0,0 +1 @@