confimration mail at end of launch process

This commit is contained in:
2025-06-20 13:36:45 +02:00
parent c9d1d7416b
commit f825bab894
5 changed files with 192 additions and 28 deletions

Binary file not shown.

View File

@@ -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',

View File

@@ -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():
<div class="credentials">
<h3>🔐 Account Access</h3>
<p><strong>Email Address:</strong> {credentials_data.get('email', 'Not set')}</p>
<p><strong>Username:</strong> {credentials_data.get('username', 'administrator')}</p>
<p><strong>Email Address:</strong> {admin_user.get('email', 'Not set')}</p>
<p><strong>Username:</strong> {admin_user.get('username', 'administrator')}</p>
<div class="security-notice">
<h4>🔒 Security Setup Required</h4>
@@ -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}")

View File

@@ -672,10 +672,6 @@ async function startLaunch(data) {
<td>Email Address</td>
<td>${credentialsResult.data.email || 'Not set'}</td>
</tr>
<tr>
<td>Password</td>
<td><code class="text-primary">${credentialsResult.data.password || 'Not set'}</code></td>
</tr>
<tr>
<td>Username</td>
<td>${credentialsResult.data.username || 'administrator'}</td>
@@ -684,6 +680,10 @@ async function startLaunch(data) {
<td>Role</td>
<td><span class="badge bg-primary">Administrator</span></td>
</tr>
<tr>
<td>Password Setup</td>
<td><span class="badge bg-warning">Reset Link Pending</span></td>
</tr>
<tr>
<td>Status</td>
<td><span class="badge bg-${credentialsResult.data.already_updated ? 'info' : 'success'}">${credentialsResult.data.already_updated ? 'Already Updated' : 'Updated'}</span></td>
@@ -693,10 +693,10 @@ async function startLaunch(data) {
</div>
<div class="alert alert-${credentialsResult.data.already_updated ? 'info' : 'warning'} mt-3">
<i class="fas fa-${credentialsResult.data.already_updated ? 'info-circle' : 'exclamation-triangle'} me-2"></i>
<strong>${credentialsResult.data.already_updated ? 'Note:' : 'Important:'}</strong>
<strong>${credentialsResult.data.already_updated ? 'Note:' : 'Security Setup Required:'}</strong>
${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.'}
</div>
<div class="alert alert-info mt-2">
<i class="fas fa-info-circle me-2"></i>
@@ -753,13 +753,146 @@ async function startLaunch(data) {
<td>Instance URL</td>
<td><a href="https://${data.webAddresses[0]}" target="_blank">https://${data.webAddresses[0]}</a></td>
</tr>
<tr>
<td>Password Reset</td>
<td><span class="badge bg-success">Link Included</span></td>
</tr>
</tbody>
</table>
</div>
<!-- Email Content Dropdown -->
<div class="accordion mt-3" id="emailContentAccordion">
<div class="accordion-item">
<h2 class="accordion-header" id="emailContentHeader">
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#emailContentCollapse" aria-expanded="false" aria-controls="emailContentCollapse">
<i class="fas fa-envelope me-2"></i>View Sent Email Content
</button>
</h2>
<div id="emailContentCollapse" class="accordion-collapse collapse" aria-labelledby="emailContentHeader" data-bs-parent="#emailContentAccordion">
<div class="accordion-body">
<div class="row">
<div class="col-md-6">
<h6 class="text-primary">HTML Version</h6>
<div class="border rounded p-3 bg-light" style="max-height: 400px; overflow-y: auto; font-size: 0.9em;">
<div class="email-preview">
<div style="font-family: Arial, sans-serif; line-height: 1.6; color: #333;">
<div style="background-color: #16767b; color: white; padding: 20px; text-align: center; border-radius: 5px 5px 0 0;">
<h1>🎉 Your DocuPulse Instance is Ready!</h1>
</div>
<div style="background-color: #f9f9f9; padding: 20px; border-radius: 0 0 5px 5px;">
<p>Dear ${data.company.name || 'Valued Customer'},</p>
<p>Great news! Your DocuPulse instance has been successfully deployed and configured.</p>
<div style="background-color: #e3f2fd; padding: 15px; border-radius: 5px; margin: 15px 0;">
<h3>📋 Instance Details</h3>
<p><strong>Instance URL:</strong> <a href="https://${data.webAddresses[0]}">https://${data.webAddresses[0]}</a></p>
<p><strong>Company Name:</strong> ${data.company.name || 'Not set'}</p>
<p><strong>Industry:</strong> ${data.company.industry || 'Not set'}</p>
<p><strong>Deployment Date:</strong> ${new Date().toLocaleString()}</p>
</div>
<div style="background-color: #e8f5e9; padding: 15px; border-radius: 5px; margin: 15px 0;">
<h3>🔐 Account Access</h3>
<p><strong>Email Address:</strong> ${data.company.email || 'Not set'}</p>
<p><strong>Username:</strong> administrator</p>
<div style="background-color: #fff3cd; border: 1px solid #ffeaa7; padding: 15px; border-radius: 5px; margin: 15px 0;">
<h4>🔒 Security Setup Required</h4>
<p>For your security, you need to set up your password. Click the button below to create your secure password.</p>
<p><strong>Password Reset Link Expires:</strong> 24 hours</p>
</div>
</div>
<div style="text-align: center; margin: 30px 0;">
<a href="#" class="btn btn-primary" style="background-color: #16767b; color: white; padding: 12px 24px; text-decoration: none; border-radius: 5px; margin: 10px 0;">🔐 Set Up Your Password</a>
<br><br>
<a href="https://${data.webAddresses[0]}" class="btn btn-primary" style="background-color: #16767b; color: white; padding: 12px 24px; text-decoration: none; border-radius: 5px; margin: 10px 0;">🚀 Access Your Instance</a>
</div>
<h3>✅ What's Been Configured</h3>
<ul>
<li>✅ Secure SSL certificate for HTTPS access</li>
<li>✅ Company information and branding</li>
<li>✅ Custom color scheme</li>
<li>✅ Admin account created</li>
<li>✅ Document management system ready</li>
</ul>
<h3>🎯 Next Steps</h3>
<ol>
<li>Click the "Set Up Your Password" button above</li>
<li>Create your secure password</li>
<li>Return to your instance and log in</li>
<li>Explore your new DocuPulse platform</li>
<li>Start uploading and organizing your documents</li>
<li>Invite team members to collaborate</li>
</ol>
<div style="margin-top: 20px; padding-top: 20px; border-top: 1px solid #ddd; font-size: 12px; color: #666;">
<p>If you have any questions or need assistance, please don't hesitate to contact our support team.</p>
<p>Thank you for choosing DocuPulse!</p>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-6">
<h6 class="text-primary">Plain Text Version</h6>
<div class="border rounded p-3 bg-light" style="max-height: 400px; overflow-y: auto; font-family: monospace; font-size: 0.85em; white-space: pre-wrap;">
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!
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="alert alert-success mt-3">
<i class="fas fa-check-circle me-2"></i>
<strong>Launch Complete!</strong> 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.
</div>
</div>
</div>