nordabiz/scripts/send_batch_password_resets.py

107 lines
3.4 KiB
Python

"""
Send password reset emails to Feb 4 batch import users who never logged in.
These users were imported with passwords but never received welcome emails.
This script generates reset tokens (24h validity) and sends reset emails.
Usage: Run on production server with DATABASE_URL set.
"""
import os
import sys
import secrets
from datetime import datetime, timedelta
# Add project root to path
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from database import SessionLocal, User, EmailLog
import email_service
# Users from Feb 4 batch import who never logged in
TARGET_USER_IDS = [53, 54, 55, 57, 58, 59, 60, 61, 62, 63, 64]
TOKEN_VALIDITY_HOURS = 24
BASE_URL = 'https://nordabiznes.pl'
def main():
if not email_service.is_configured():
print("ERROR: Email service not configured. Set credentials in .env")
sys.exit(1)
db = SessionLocal()
try:
results = {'sent': [], 'failed': [], 'skipped': []}
for user_id in TARGET_USER_IDS:
user = db.query(User).get(user_id)
if not user:
results['skipped'].append(f"ID {user_id}: not found")
continue
if not user.is_active:
results['skipped'].append(f"{user.email}: inactive")
continue
if user.last_login is not None:
results['skipped'].append(f"{user.email}: already logged in")
continue
# Generate token
token = secrets.token_urlsafe(32)
expires = datetime.now() + timedelta(hours=TOKEN_VALIDITY_HOURS)
user.reset_token = token
user.reset_token_expires = expires
db.commit()
reset_url = f"{BASE_URL}/reset-password/{token}"
# Send email
try:
success = email_service.send_password_reset_email(user.email, reset_url)
if success:
# Log the email
log = EmailLog(
email_type='password_reset',
recipient_email=user.email,
recipient_name=user.name,
subject='Reset hasła - Norda Biznes Partner',
status='sent',
sent_at=datetime.now(),
created_at=datetime.now(),
)
db.add(log)
db.commit()
results['sent'].append(f"{user.name} <{user.email}>")
print(f" OK: {user.name} <{user.email}>")
else:
results['failed'].append(f"{user.name} <{user.email}>: send returned False")
print(f" FAIL: {user.name} <{user.email}>")
except Exception as e:
results['failed'].append(f"{user.name} <{user.email}>: {e}")
print(f" ERROR: {user.name} <{user.email}>: {e}")
print(f"\n{'='*50}")
print(f"Sent: {len(results['sent'])}")
print(f"Failed: {len(results['failed'])}")
print(f"Skipped: {len(results['skipped'])}")
if results['failed']:
print(f"\nFailed details:")
for f in results['failed']:
print(f" - {f}")
if results['skipped']:
print(f"\nSkipped details:")
for s in results['skipped']:
print(f" - {s}")
finally:
db.close()
if __name__ == '__main__':
main()