新增功能: 1. 修改密码功能 - 用户可以修改自己的密码 - 需要验证旧密码 - 新密码至少6位且不能与旧密码相同 2. 邮箱绑定功能 - 用户可以绑定/修改邮箱 - 邮箱格式验证和唯一性检查 - 修改邮箱后需要重新验证 3. 邮箱验证功能 - 发送验证邮件(24小时有效) - 点击邮件链接完成验证 - 验证状态显示 技术实现: - 新增4个数据库字段(email_verified等) - 封装邮件发送工具(utils/email_sender.py) - 新增5个API接口 - 新增修改密码页面 - 集成邮箱管理到个人中心 文件变更: - 修改:app.py, models.py, base_new.html, profile.html - 新增:change_password.html, email_sender.py, migrate_email_verification.py - 文档:server-update.md, SERVER_RESTART_GUIDE.md Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
74 lines
2.4 KiB
Python
74 lines
2.4 KiB
Python
"""
|
||
邮件发送工具模块
|
||
支持发送验证邮件、通知邮件等
|
||
"""
|
||
|
||
import os
|
||
import smtplib
|
||
from email.mime.text import MIMEText
|
||
from email.mime.multipart import MIMEMultipart
|
||
from email.header import Header
|
||
import logging
|
||
|
||
logger = logging.getLogger(__name__)
|
||
|
||
|
||
class EmailSender:
|
||
"""邮件发送器"""
|
||
|
||
def __init__(self):
|
||
"""初始化邮件配置"""
|
||
self.smtp_server = os.environ.get('SMTP_SERVER', 'smtp.gmail.com')
|
||
self.smtp_port = int(os.environ.get('SMTP_PORT', '587'))
|
||
self.smtp_user = os.environ.get('SMTP_USER', '')
|
||
self.smtp_password = os.environ.get('SMTP_PASSWORD', '')
|
||
self.from_email = os.environ.get('FROM_EMAIL', self.smtp_user)
|
||
self.from_name = os.environ.get('FROM_NAME', 'ZJPB')
|
||
|
||
def send_email(self, to_email, subject, html_content, text_content=None):
|
||
"""
|
||
发送邮件
|
||
|
||
Args:
|
||
to_email: 收件人邮箱
|
||
subject: 邮件主题
|
||
html_content: HTML格式邮件内容
|
||
text_content: 纯文本格式邮件内容(可选)
|
||
|
||
Returns:
|
||
bool: 发送是否成功
|
||
"""
|
||
try:
|
||
# 检查配置
|
||
if not self.smtp_user or not self.smtp_password:
|
||
logger.error('邮件配置不完整,请设置SMTP_USER和SMTP_PASSWORD环境变量')
|
||
return False
|
||
|
||
# 创建邮件对象
|
||
message = MIMEMultipart('alternative')
|
||
message['From'] = f'{self.from_name} <{self.from_email}>'
|
||
message['To'] = to_email
|
||
message['Subject'] = Header(subject, 'utf-8')
|
||
|
||
# 添加纯文本内容
|
||
if text_content:
|
||
text_part = MIMEText(text_content, 'plain', 'utf-8')
|
||
message.attach(text_part)
|
||
|
||
# 添加HTML内容
|
||
html_part = MIMEText(html_content, 'html', 'utf-8')
|
||
message.attach(html_part)
|
||
|
||
# 连接SMTP服务器并发送
|
||
with smtplib.SMTP(self.smtp_server, self.smtp_port) as server:
|
||
server.starttls() # 启用TLS加密
|
||
server.login(self.smtp_user, self.smtp_password)
|
||
server.send_message(message)
|
||
|
||
logger.info(f'邮件发送成功: {to_email}')
|
||
return True
|
||
|
||
except Exception as e:
|
||
logger.error(f'邮件发送失败: {str(e)}')
|
||
return False
|