Whole new user interface and user system

This commit is contained in:
2025-09-30 15:47:57 -06:00
parent 75fefb20cb
commit acd2234db5
26 changed files with 4125 additions and 134 deletions

View File

@@ -26,28 +26,7 @@ class EmailService {
};
}
this.transporter = nodemailer.createTransporter(transporterConfig);
console.log('Email transporter initialized successfully');
} catch (error) {
console.error('Failed to initialize email transporter:', error);
}
}
initializeTransporter() {
try {
this.transporter = nodemailer.createTransport({
host: process.env.SMTP_HOST,
port: parseInt(process.env.SMTP_PORT) || 587,
secure: process.env.SMTP_PORT === '465', // true for 465, false for other ports
auth: {
user: process.env.SMTP_USER,
pass: process.env.SMTP_PASS
},
tls: {
rejectUnauthorized: false
}
});
this.transporter = nodemailer.createTransport(transporterConfig);
console.log('Email transporter initialized successfully');
} catch (error) {
@@ -352,6 +331,62 @@ class EmailService {
throw error;
}
}
// User management email methods
async sendLoginDetails(user) {
try {
const baseUrl = process.env.BASE_URL || `http://localhost:${process.env.PORT || 3333}`;
const isAdmin = user.admin || user.Admin || false;
const templateVariables = {
APP_NAME: 'BNKops Influence',
USER_NAME: user.Name || user.name || user.Email || user.email,
USER_EMAIL: user.Email || user.email,
PASSWORD: user.Password || user.password,
USER_ROLE: isAdmin ? 'Administrator' : 'User',
LOGIN_URL: `${baseUrl}/login.html`,
TIMESTAMP: new Date().toLocaleString()
};
const emailOptions = {
to: user.Email || user.email,
from: {
email: process.env.SMTP_FROM_EMAIL,
name: process.env.SMTP_FROM_NAME
},
subject: `Your Login Details - ${templateVariables.APP_NAME}`
};
return await this.sendTemplatedEmail('login-details', templateVariables, emailOptions);
} catch (error) {
console.error('Failed to send login details email:', error);
throw error;
}
}
async sendEmail(emailOptions) {
try {
if (!this.transporter) {
throw new Error('Email transporter not initialized');
}
const mailOptions = {
from: `${process.env.SMTP_FROM_NAME || 'BNKops Influence'} <${process.env.SMTP_FROM_EMAIL || 'noreply@example.com'}>`,
to: emailOptions.to,
subject: emailOptions.subject,
text: emailOptions.text,
html: emailOptions.html
};
const info = await this.transporter.sendMail(mailOptions);
console.log(`Email sent: ${info.messageId}`);
return info;
} catch (error) {
console.error('Failed to send email:', error);
throw error;
}
}
}
module.exports = new EmailService();

View File

@@ -430,7 +430,10 @@ class NocoDBService {
'Collect User Info': campaignData.collect_user_info,
'Show Email Count': campaignData.show_email_count,
'Allow Email Editing': campaignData.allow_email_editing,
'Target Government Levels': campaignData.target_government_levels
'Target Government Levels': campaignData.target_government_levels,
'Created By User ID': campaignData.created_by_user_id,
'Created By User Email': campaignData.created_by_user_email,
'Created By User Name': campaignData.created_by_user_name
};
const response = await this.create(this.tableIds.campaigns, mappedData);
@@ -604,13 +607,18 @@ class NocoDBService {
if (!this.tableIds.users) {
throw new Error('Users table not configured');
}
const response = await this.getAll(this.tableIds.users, {
where: `(Email,eq,${email})`,
limit: 1
});
return response.list?.[0] || null;
try {
const response = await this.getAll(this.tableIds.users, {
where: `(Email,eq,${email})`,
limit: 1
});
return response.list?.[0] || null;
} catch (error) {
console.error('Error in getUserByEmail:', error.message);
throw error;
}
}
async createUser(userData) {
@@ -633,8 +641,21 @@ class NocoDBService {
if (!this.tableIds.users) {
throw new Error('Users table not configured');
}
return await this.delete(this.tableIds.users, userId);
const url = `${this.getTableUrl(this.tableIds.users)}/${userId}`;
const response = await this.client.delete(url);
return response.data;
}
async getById(tableId, recordId) {
try {
const url = `${this.getTableUrl(tableId)}/${recordId}`;
const response = await this.client.get(url);
return response.data;
} catch (error) {
console.error('Error getting record by ID:', error);
throw error;
}
}
async getAllUsers(params = {}) {