diff --git a/__pycache__/app.cpython-313.pyc b/__pycache__/app.cpython-313.pyc index 9f46eac..ae90487 100644 Binary files a/__pycache__/app.cpython-313.pyc and b/__pycache__/app.cpython-313.pyc differ diff --git a/routes/__pycache__/main.cpython-313.pyc b/routes/__pycache__/main.cpython-313.pyc index db51785..218c737 100644 Binary files a/routes/__pycache__/main.cpython-313.pyc and b/routes/__pycache__/main.cpython-313.pyc differ diff --git a/routes/admin_api.py b/routes/admin_api.py index 35490ea..6f0dd12 100644 --- a/routes/admin_api.py +++ b/routes/admin_api.py @@ -550,8 +550,12 @@ def generate_password_reset_token(current_user, user_id): db.session.add(reset_token) db.session.commit() + # Get the instance URL from the request data or use the current host + data = request.get_json() or {} + instance_url = data.get('instance_url', request.host_url.rstrip('/')) + # Return the token and reset URL - reset_url = f"{request.host_url.rstrip('/')}/reset-password/{token}" + reset_url = f"{instance_url}/reset-password/{token}" return jsonify({ 'message': 'Password reset token generated successfully', diff --git a/routes/launch_api.py b/routes/launch_api.py index 0717099..0658ceb 100644 --- a/routes/launch_api.py +++ b/routes/launch_api.py @@ -4,11 +4,15 @@ from models import ( Instance ) from extensions import db, csrf +from routes.admin_api import token_required +import json +import smtplib +from email.mime.text import MIMEText +from email.mime.multipart import MIMEMultipart +from email.utils import formatdate from datetime import datetime import requests import base64 -from routes.admin_api import token_required -import json launch_api = Blueprint('launch_api', __name__) @@ -1117,9 +1121,9 @@ def update_admin_credentials(): users_data = users_response.json() admin_user = None - # Find the administrator user + # Find the administrator user by role (since email was already updated) for user in users_data: - if user.get('email') == email: + if user.get('is_admin') == True: admin_user = user break @@ -1291,9 +1295,9 @@ def send_completion_email(): users_data = users_response.json() admin_user = None - # Find the administrator user by email + # Find the administrator user by role (since email was already updated) for user in users_data: - if user.get('email') == credentials_data.get('email'): + if user.get('is_admin') == True: admin_user = user break @@ -1307,8 +1311,10 @@ def send_completion_email(): f"{instance_url.rstrip('/')}/api/admin/generate-password-reset/{admin_user_id}", headers={ 'Authorization': f'Bearer {jwt_token}', - 'Accept': 'application/json' + 'Accept': 'application/json', + 'Content-Type': 'application/json' }, + json={'instance_url': instance_url}, timeout=10 ) @@ -1364,8 +1370,8 @@ def send_completion_email():

🔐 Account Access

-

Email Address: {credentials_data.get('email', 'Not set')}

-

Username: {credentials_data.get('username', 'administrator')}

+

Email Address: {admin_user.get('email', 'Not set')}

+

Username: {admin_user.get('username', 'administrator')}

🔒 Security Setup Required

@@ -1424,8 +1430,8 @@ INSTANCE DETAILS: - Deployment Date: {datetime.utcnow().strftime('%B %d, %Y at %I:%M %p UTC')} ACCOUNT ACCESS: -- Email Address: {credentials_data.get('email', 'Not set')} -- Username: {credentials_data.get('username', 'administrator')} +- Email Address: {admin_user.get('email', 'Not set')} +- Username: {admin_user.get('username', 'administrator')} SECURITY SETUP REQUIRED: For your security, you need to set up your password. @@ -1454,15 +1460,36 @@ Thank you for choosing DocuPulse! """ # Send email using master instance's email system - from utils.email_templates import send_email - try: - send_email( - to_email=company_data.get('email'), - subject=subject, - html_content=html_content, - text_content=text_content - ) + # Get SMTP settings + smtp_settings = KeyValueSettings.get_value('smtp_settings') + if not smtp_settings: + return jsonify({'error': 'SMTP settings not configured'}), 400 + + # Create message + msg = MIMEMultipart() + msg['From'] = f"{smtp_settings.get('smtp_from_name', 'DocuPulse')} <{smtp_settings.get('smtp_from_email')}>" + msg['To'] = company_data.get('email') + msg['Subject'] = subject + msg['Date'] = formatdate(localtime=True) + + # Add HTML content + msg.attach(MIMEText(html_content, 'html')) + + # Send email + if smtp_settings.get('smtp_security') == 'ssl': + server = smtplib.SMTP_SSL(smtp_settings.get('smtp_host'), smtp_settings.get('smtp_port')) + else: + server = smtplib.SMTP(smtp_settings.get('smtp_host'), smtp_settings.get('smtp_port')) + + if smtp_settings.get('smtp_security') == 'tls': + server.starttls() + + if smtp_settings.get('smtp_username') and smtp_settings.get('smtp_password'): + server.login(smtp_settings.get('smtp_username'), smtp_settings.get('smtp_password')) + + server.send_message(msg) + server.quit() # Log the email sending current_app.logger.info(f"Completion email sent to {company_data.get('email')} for instance {instance_url}") @@ -1476,7 +1503,7 @@ Thank you for choosing DocuPulse! 'password_reset_sent': True } }) - + except Exception as email_error: current_app.logger.error(f"Failed to send completion email: {str(email_error)}") return jsonify({'error': f'Failed to send email: {str(email_error)}'}), 500 diff --git a/static/js/launch_progress.js b/static/js/launch_progress.js index 4230d30..b3159d8 100644 --- a/static/js/launch_progress.js +++ b/static/js/launch_progress.js @@ -672,10 +672,6 @@ async function startLaunch(data) { Email Address ${credentialsResult.data.email || 'Not set'} - - Password - ${credentialsResult.data.password || 'Not set'} - Username ${credentialsResult.data.username || 'administrator'} @@ -684,6 +680,10 @@ async function startLaunch(data) { Role Administrator + + Password Setup + Reset Link Pending + Status ${credentialsResult.data.already_updated ? 'Already Updated' : 'Updated'} @@ -693,10 +693,10 @@ async function startLaunch(data) {
- ${credentialsResult.data.already_updated ? 'Note:' : 'Important:'} + ${credentialsResult.data.already_updated ? 'Note:' : 'Security Setup Required:'} ${credentialsResult.data.already_updated ? 'Admin credentials were already updated from the default settings.' : - 'Please save these credentials securely. The password will not be shown again.'} + 'A secure password reset link will be sent to the admin email address in the completion email.'}
@@ -753,13 +753,146 @@ async function startLaunch(data) { Instance URL https://${data.webAddresses[0]} + + Password Reset + Link Included +
+ + +
+
+

+ +

+
+
+
+
+
HTML Version
+
+ +
+
+
+
Plain Text Version
+
+Your DocuPulse Instance is Ready! + +Dear ${data.company.name || 'Valued Customer'}, + +Great news! Your DocuPulse instance has been successfully deployed and configured. + +INSTANCE DETAILS: +- Instance URL: https://${data.webAddresses[0]} +- Company Name: ${data.company.name || 'Not set'} +- Industry: ${data.company.industry || 'Not set'} +- Deployment Date: ${new Date().toLocaleString()} + +ACCOUNT ACCESS: +- Email Address: ${data.company.email || 'Not set'} +- Username: administrator + +SECURITY SETUP REQUIRED: +For your security, you need to set up your password. + +Password Reset Link: [Secure reset link included] +Password Reset Link Expires: 24 hours + +WHAT'S BEEN CONFIGURED: +✓ Secure SSL certificate for HTTPS access +✓ Company information and branding +✓ Custom color scheme +✓ Admin account created +✓ Document management system ready + +NEXT STEPS: +1. Click the password reset link above +2. Create your secure password +3. Return to your instance and log in +4. Explore your new DocuPulse platform +5. Start uploading and organizing your documents +6. Invite team members to collaborate + +If you have any questions or need assistance, please don't hesitate to contact our support team. + +Thank you for choosing DocuPulse! +
+
+
+
+
+
+
+
Launch Complete! Your DocuPulse instance has been successfully deployed and configured. - The client has been notified via email with all necessary login information. + The client has been notified via email with all necessary login information and a secure password reset link.