added admin email notification
This commit is contained in:
@@ -219,6 +219,7 @@ const smtpUser = process.env.SMTP_USER?.trim() ?? '';
|
||||
const smtpPass = process.env.SMTP_PASS?.trim() ?? '';
|
||||
const smtpFromEmail = process.env.SMTP_FROM_EMAIL?.trim() ?? '';
|
||||
const smtpFromName = process.env.SMTP_FROM_NAME?.trim() || 'FlockPal';
|
||||
const rescueStatusNotificationEmail = process.env.RESCUE_STATUS_NOTIFICATION_EMAIL?.trim() || 'appadmin@flockpal.app';
|
||||
const adminEmails = new Set(
|
||||
(process.env.ADMIN_EMAILS ?? '')
|
||||
.split(',')
|
||||
@@ -487,6 +488,64 @@ const sendMagicLink = async ({
|
||||
};
|
||||
};
|
||||
|
||||
const escapeHtml = (value: string) =>
|
||||
value
|
||||
.replace(/&/g, '&')
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>')
|
||||
.replace(/"/g, '"')
|
||||
.replace(/'/g, ''');
|
||||
|
||||
const sendRescueStatusNotification = async ({
|
||||
workspace,
|
||||
ownerEmail,
|
||||
event,
|
||||
}: {
|
||||
workspace: WorkspaceRow;
|
||||
ownerEmail: string | null;
|
||||
event: 'created' | 'converted' | 'status_changed';
|
||||
}) => {
|
||||
const statusLabel = workspace.rescue_verification_status.replace(/_/g, ' ');
|
||||
const eventLabel = event === 'created' ? 'created' : event === 'converted' ? 'converted to rescue' : 'status updated';
|
||||
const subject = `FlockPal rescue status: ${workspace.name} ${eventLabel}`;
|
||||
const escapedWorkspaceName = escapeHtml(workspace.name);
|
||||
const escapedStatusLabel = escapeHtml(statusLabel);
|
||||
const escapedOwnerEmail = escapeHtml(ownerEmail ?? 'unknown');
|
||||
const escapedBillingEmail = escapeHtml(workspace.billing_email ?? 'not set');
|
||||
const lines = [
|
||||
`Rescue flock: ${workspace.name}`,
|
||||
`Event: ${eventLabel}`,
|
||||
`Verification status: ${statusLabel}`,
|
||||
`Owner email: ${ownerEmail ?? 'unknown'}`,
|
||||
`Billing email: ${workspace.billing_email ?? 'not set'}`,
|
||||
`Flock ID: ${workspace.id}`,
|
||||
];
|
||||
|
||||
if (!mailTransport) {
|
||||
console.log(`Rescue status notification for ${rescueStatusNotificationEmail}:\n${lines.join('\n')}`);
|
||||
return { delivered: false };
|
||||
}
|
||||
|
||||
await mailTransport.sendMail({
|
||||
from: smtpFromName ? `"${smtpFromName}" <${smtpFromEmail}>` : smtpFromEmail,
|
||||
to: rescueStatusNotificationEmail,
|
||||
subject,
|
||||
text: lines.join('\n'),
|
||||
html: `
|
||||
<p>A rescue flock was ${eventLabel}.</p>
|
||||
<ul>
|
||||
<li><strong>Rescue flock:</strong> ${escapedWorkspaceName}</li>
|
||||
<li><strong>Verification status:</strong> ${escapedStatusLabel}</li>
|
||||
<li><strong>Owner email:</strong> ${escapedOwnerEmail}</li>
|
||||
<li><strong>Billing email:</strong> ${escapedBillingEmail}</li>
|
||||
<li><strong>Flock ID:</strong> ${workspace.id}</li>
|
||||
</ul>
|
||||
`,
|
||||
});
|
||||
|
||||
return { delivered: true };
|
||||
};
|
||||
|
||||
const issueMagicLinkInvite = async ({
|
||||
email,
|
||||
name,
|
||||
@@ -1006,6 +1065,12 @@ app.patch('/api/admin/rescue-workspaces/:workspaceId', requireAuth, requireSessi
|
||||
return;
|
||||
}
|
||||
|
||||
await sendRescueStatusNotification({
|
||||
workspace,
|
||||
ownerEmail: null,
|
||||
event: 'status_changed',
|
||||
});
|
||||
|
||||
res.json({ workspace: normalizeWorkspace(workspace) });
|
||||
} catch (error) {
|
||||
next(error);
|
||||
@@ -1098,6 +1163,14 @@ app.post('/api/workspaces', requireAuth, requireSessionAuth, async (req: Request
|
||||
owner: req.auth!.user,
|
||||
});
|
||||
|
||||
if (workspace?.workspace_type === 'rescue') {
|
||||
await sendRescueStatusNotification({
|
||||
workspace,
|
||||
ownerEmail: req.auth!.user.email,
|
||||
event: 'created',
|
||||
});
|
||||
}
|
||||
|
||||
res.status(201).json({ workspace: normalizeWorkspace(workspace!) });
|
||||
} catch (error) {
|
||||
next(error);
|
||||
@@ -1126,6 +1199,14 @@ app.put('/api/workspace', requireAuth, requireWriteAccess, requireWorkspaceRole(
|
||||
billingPlan,
|
||||
});
|
||||
|
||||
if (workspace?.workspace_type === 'rescue' && req.auth!.workspace.workspace_type !== 'rescue') {
|
||||
await sendRescueStatusNotification({
|
||||
workspace,
|
||||
ownerEmail: req.auth!.user.email,
|
||||
event: 'converted',
|
||||
});
|
||||
}
|
||||
|
||||
res.json({ workspace: normalizeWorkspace(workspace!) });
|
||||
} catch (error) {
|
||||
next(error);
|
||||
|
||||
Reference in New Issue
Block a user