new system for creating campaigns from the main site dashboard

This commit is contained in:
2025-10-15 10:32:18 -06:00
parent 4b14f2d099
commit 87a58ba862
12 changed files with 956 additions and 3 deletions

View File

@@ -1,5 +1,6 @@
const emailService = require('../services/email');
const nocoDB = require('../services/nocodb');
const crypto = require('crypto');
class EmailsController {
async sendEmail(req, res, next) {
@@ -211,6 +212,206 @@ class EmailsController {
});
}
}
async initiateEmailToCampaign(req, res, next) {
try {
const { email, subject, message, postalCode, senderName } = req.body;
// Check if email verification is enabled
const verificationEnabled = process.env.EMAIL_VERIFICATION_ENABLED !== 'false';
if (!verificationEnabled) {
return res.status(400).json({
success: false,
error: 'Email verification is not enabled'
});
}
// Generate verification token
const token = crypto.randomBytes(32).toString('hex');
const expiryHours = parseInt(process.env.EMAIL_VERIFICATION_EXPIRY) || 24;
const expiresAt = new Date(Date.now() + expiryHours * 60 * 60 * 1000);
// Store token and campaign data
await nocoDB.createEmailVerification({
token,
email,
temp_campaign_data: JSON.stringify({
subject,
message,
postalCode,
senderName
}),
created_at: new Date().toISOString(),
expires_at: expiresAt.toISOString(),
used: false
});
// Send verification email
const appUrl = process.env.APP_URL || 'http://localhost:3333';
const verificationUrl = `${appUrl}/verify-email.html?token=${token}`;
await emailService.sendEmailVerification(email, verificationUrl, senderName || 'there');
res.json({
success: true,
message: 'Verification email sent. Please check your inbox.'
});
} catch (error) {
console.error('Email to campaign conversion error:', error);
res.status(500).json({
success: false,
error: 'Failed to initiate campaign conversion',
message: error.message
});
}
}
async verifyEmailToken(req, res, next) {
try {
const { token } = req.params;
// Find verification record
const verification = await nocoDB.getEmailVerificationByToken(token);
if (!verification) {
return res.status(404).json({
success: false,
error: 'Invalid or expired verification link'
});
}
// Check if already used
if (verification.used) {
return res.status(400).json({
success: false,
error: 'This verification link has already been used'
});
}
// Check if expired
const now = new Date();
const expiresAt = new Date(verification.expires_at || verification.expiresAt || verification['Expires At']);
if (now > expiresAt) {
return res.status(400).json({
success: false,
error: 'This verification link has expired'
});
}
// Mark as used
const verificationId = verification.id || verification.Id || verification.ID;
await nocoDB.updateEmailVerification(verificationId, { used: true });
// Parse campaign data
const campaignDataStr = verification.temp_campaign_data || verification.tempCampaignData || verification['Temp Campaign Data'];
const campaignData = JSON.parse(campaignDataStr);
// Check if user exists
const userEmail = verification.email || verification.Email;
const existingUser = await nocoDB.getUserByEmail(userEmail);
if (existingUser) {
// User exists, log them in automatically
req.session.authenticated = true;
req.session.userId = existingUser.ID || existingUser.Id || existingUser.id;
req.session.userEmail = existingUser.Email || existingUser.email;
req.session.userName = existingUser.Name || existingUser.name;
req.session.isAdmin = existingUser.Admin || existingUser.admin || false;
req.session.userType = existingUser['User Type'] || existingUser.UserType || existingUser.userType || 'user';
req.session.save((err) => {
if (err) {
console.error('Session save error:', err);
return res.status(500).json({
success: false,
error: 'Session error'
});
}
res.json({
success: true,
needsAccount: false,
campaignData: campaignData,
redirectTo: '/dashboard.html'
});
});
} else {
// User doesn't exist - create a new user account automatically
try {
// Generate a temporary password (user can change it later)
const tempPassword = crypto.randomBytes(16).toString('hex');
// Extract name from campaign data or use email prefix
const userName = campaignData.senderName || userEmail.split('@')[0];
// Create new user
const newUser = await nocoDB.createUser({
'Name': userName,
'Email': userEmail,
'Password': tempPassword,
'Admin': false,
'User Type': 'user'
});
const userId = newUser.ID || newUser.Id || newUser.id || newUser;
// Send login credentials email to the new user
try {
await emailService.sendLoginDetails({
Name: userName,
Email: userEmail,
Password: tempPassword,
admin: false
});
console.log('Welcome email with credentials sent to:', userEmail);
} catch (emailError) {
console.error('Failed to send welcome email:', emailError);
// Don't fail the whole process if email sending fails
}
// Log the new user in automatically
req.session.authenticated = true;
req.session.userId = userId;
req.session.userEmail = userEmail;
req.session.userName = userName;
req.session.isAdmin = false;
req.session.userType = 'user';
req.session.save((err) => {
if (err) {
console.error('Session save error:', err);
return res.status(500).json({
success: false,
error: 'Session error'
});
}
res.json({
success: true,
needsAccount: false,
isNewUser: true,
campaignData: campaignData,
redirectTo: '/dashboard.html',
message: 'Account created successfully! Check your email for login credentials.'
});
});
} catch (createError) {
console.error('Error creating user account:', createError);
return res.status(500).json({
success: false,
error: 'Failed to create user account',
message: createError.message
});
}
}
} catch (error) {
console.error('Email verification error:', error);
res.status(500).json({
success: false,
error: 'Failed to verify email',
message: error.message
});
}
}
}
module.exports = new EmailsController();