Harden auth, payments, and frontend against review findings.
Close exploitable gaps in booking/payment flows, enforce token versioning and account checks, gate sensitive payment data, and add middleware plus input validation across admin routes. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -247,10 +247,20 @@ async function sendWithConsole(options: SendEmailOptions): Promise<SendEmailResu
|
||||
/**
|
||||
* Main send function that routes to the appropriate provider
|
||||
*/
|
||||
// Mask an email address for logs: keep first char + domain (e.g. j***@example.com).
|
||||
function maskEmail(email: string): string {
|
||||
const [local, domain] = String(email).split('@');
|
||||
if (!domain) return '***';
|
||||
const head = local.slice(0, 1);
|
||||
return `${head}***@${domain}`;
|
||||
}
|
||||
|
||||
async function sendEmail(options: SendEmailOptions): Promise<SendEmailResult> {
|
||||
const provider = getEmailProvider();
|
||||
|
||||
console.log(`[Email] Sending email via ${provider} to ${Array.isArray(options.to) ? options.to.join(', ') : options.to}`);
|
||||
const recipientCount = Array.isArray(options.to) ? options.to.length : 1;
|
||||
const sample = Array.isArray(options.to) ? options.to[0] : options.to;
|
||||
console.log(`[Email] Sending email via ${provider} to ${maskEmail(sample)}${recipientCount > 1 ? ` (+${recipientCount - 1} more)` : ''}`);
|
||||
|
||||
switch (provider) {
|
||||
case 'resend':
|
||||
@@ -478,7 +488,7 @@ export const emailService = {
|
||||
|
||||
// Replace variables
|
||||
const finalSubject = replaceTemplateVariables(subject, allVariables);
|
||||
const finalBodyContent = replaceTemplateVariables(bodyHtml, allVariables);
|
||||
const finalBodyContent = replaceTemplateVariables(bodyHtml, allVariables, true);
|
||||
const finalBodyHtml = wrapInBaseTemplate(finalBodyContent, { ...allVariables, subject: finalSubject });
|
||||
const finalBodyText = bodyText ? replaceTemplateVariables(bodyText, allVariables) : undefined;
|
||||
|
||||
@@ -1292,7 +1302,14 @@ export const emailService = {
|
||||
eventId?: string;
|
||||
sentBy?: string | null;
|
||||
}): Promise<{ success: boolean; logId?: string; error?: string }> {
|
||||
const { to, toName, subject, bodyHtml, bodyText, replyTo, eventId, sentBy = null } = params;
|
||||
const { to: rawTo, toName, subject: rawSubject, bodyHtml, bodyText, replyTo: rawReplyTo, eventId, sentBy = null } = params;
|
||||
|
||||
// Strip CR/LF from header-bound values to prevent email header injection
|
||||
// (e.g. an attacker-supplied subject/replyTo smuggling extra headers/recipients).
|
||||
const stripHeader = (v?: string) => (v ? v.replace(/[\r\n]+/g, ' ').trim() : v);
|
||||
const to = stripHeader(rawTo) as string;
|
||||
const subject = stripHeader(rawSubject) as string;
|
||||
const replyTo = stripHeader(rawReplyTo);
|
||||
|
||||
const allVariables = {
|
||||
...this.getCommonVariables(),
|
||||
|
||||
Reference in New Issue
Block a user