notifications

This commit is contained in:
Alex Holliday committed 2025-12-11 15:20:21 -08:00
1 parent 63dd455e4a
commit 22f7d002fd
7 files changed
+128 -107

No files matched your search

+2 -23
View File
@@ -81,7 +81,6 @@
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.5.tgz",
"integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==",
"license": "MIT",
"peer": true,
"dependencies": {
"@babel/code-frame": "^7.27.1",
"@babel/generator": "^7.28.5",
@@ -417,7 +416,6 @@
"resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.14.0.tgz",
"integrity": "sha512-O000MLDBDdk/EohJPFUqvnp4qnHeYkVP5B0xEG0D/L7cOKP9kefu2DXn8dj74cQfsEzUqh+sr1RzFqiL1o+PpA==",
"license": "MIT",
"peer": true,
"dependencies": {
"@babel/runtime": "^7.18.3",
"@emotion/babel-plugin": "^11.13.5",
@@ -461,7 +459,6 @@
"resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.14.1.tgz",
"integrity": "sha512-qEEJt42DuToa3gurlH4Qqc1kVpNq8wO8cJtDzU46TjlzWjDlsVyevtYCRijVq3SrHsROS+gVQ8Fnea108GnKzw==",
"license": "MIT",
"peer": true,
"dependencies": {
"@babel/runtime": "^7.18.3",
"@emotion/babel-plugin": "^11.13.5",
@@ -1204,7 +1201,6 @@
"resolved": "https://registry.npmjs.org/@mui/material/-/material-7.3.4.tgz",
"integrity": "sha512-gEQL9pbJZZHT7lYJBKQCS723v1MGys2IFc94COXbUIyCTWa+qC77a7hUax4Yjd5ggEm35dk4AyYABpKKWC4MLw==",
"license": "MIT",
"peer": true,
"dependencies": {
"@babel/runtime": "^7.28.4",
"@mui/core-downloads-tracker": "^7.3.4",
@@ -1315,7 +1311,6 @@
"resolved": "https://registry.npmjs.org/@mui/system/-/system-7.3.5.tgz",
"integrity": "sha512-yPaf5+gY3v80HNkJcPi6WT+r9ebeM4eJzrREXPxMt7pNTV/1eahyODO4fbH3Qvd8irNxDFYn5RQ3idHW55rA6g==",
"license": "MIT",
"peer": true,
"dependencies": {
"@babel/runtime": "^7.28.4",
"@mui/private-theming": "^7.3.5",
@@ -2300,7 +2295,6 @@
"integrity": "sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ==",
"devOptional": true,
"license": "MIT",
"peer": true,
"dependencies": {
"undici-types": "~7.16.0"
}
@@ -2322,7 +2316,6 @@
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.2.tgz",
"integrity": "sha512-6mDvHUFSjyT2B2yeNx2nUgMxh9LtOWvkhIU3uePn2I2oyNymUAX1NIsdgviM4CH+JSrp2D2hsMvJOkxY+0wNRA==",
"license": "MIT",
"peer": true,
"dependencies": {
"csstype": "^3.0.2"
}
@@ -2398,7 +2391,6 @@
"integrity": "sha512-6m1I5RmHBGTnUGS113G04DMu3CpSdxCAU/UvtjNWL4Nuf3MW9tQhiJqRlHzChIkhy6kZSAQmc+I1bcGjE3yNKg==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@typescript-eslint/scope-manager": "8.46.3",
"@typescript-eslint/types": "8.46.3",
@@ -2651,7 +2643,6 @@
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
"dev": true,
"license": "MIT",
"peer": true,
"bin": {
"acorn": "bin/acorn"
},
@@ -2819,7 +2810,6 @@
}
],
"license": "MIT",
"peer": true,
"dependencies": {
"baseline-browser-mapping": "^2.8.19",
"caniuse-lite": "^1.0.30001751",
@@ -3156,8 +3146,7 @@
"version": "1.11.18",
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.18.tgz",
"integrity": "sha512-zFBQ7WFRvVRhKcWoUh+ZA1g2HVgUbsZm9sbddh8EC5iv93sui8DVVz1Npvz+r6meo9VKfa8NyLWBsQK1VvIKPA==",
"license": "MIT",
"peer": true
"license": "MIT"
},
"node_modules/debug": {
"version": "4.4.3",
@@ -3391,7 +3380,6 @@
"integrity": "sha512-BhHmn2yNOFA9H9JmmIVKJmd288g9hrVRDkdoIgRCRuSySRUHH7r/DI6aAXW9T1WwUuY3DFgrcaqB+deURBLR5g==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.8.0",
"@eslint-community/regexpp": "^4.12.1",
@@ -4710,7 +4698,6 @@
"resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz",
"integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==",
"license": "MIT",
"peer": true,
"dependencies": {
"loose-envify": "^1.1.0"
},
@@ -4723,7 +4710,6 @@
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz",
"integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==",
"license": "MIT",
"peer": true,
"dependencies": {
"loose-envify": "^1.1.0",
"scheduler": "^0.23.2"
@@ -4786,7 +4772,6 @@
"resolved": "https://registry.npmjs.org/react-redux/-/react-redux-9.2.0.tgz",
"integrity": "sha512-ROY9fvHhwOD9ySfrF0wmvu//bKCQ6AeZZq1nJNtbDC+kk5DuSuNX/n6YWYF/SYy7bSba4D4FSz8DJeKY/S/r+g==",
"license": "MIT",
"peer": true,
"dependencies": {
"@types/use-sync-external-store": "^0.0.6",
"use-sync-external-store": "^1.4.0"
@@ -4939,8 +4924,7 @@
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz",
"integrity": "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==",
"license": "MIT",
"peer": true
"license": "MIT"
},
"node_modules/redux-persist": {
"version": "6.0.0",
@@ -5011,7 +4995,6 @@
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.52.5.tgz",
"integrity": "sha512-3GuObel8h7Kqdjt0gxkEzaifHTqLVW56Y/bjN7PSQtkKr0w3V/QYSdt6QWYtd7A1xUtYQigtdUfgj1RvWVtorw==",
"license": "MIT",
"peer": true,
"dependencies": {
"@types/estree": "1.0.8"
},
@@ -5254,7 +5237,6 @@
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
"license": "MIT",
"peer": true,
"engines": {
"node": ">=12"
},
@@ -5370,7 +5352,6 @@
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
"devOptional": true,
"license": "Apache-2.0",
"peer": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
@@ -5493,7 +5474,6 @@
"resolved": "https://registry.npmjs.org/vite/-/vite-7.2.1.tgz",
"integrity": "sha512-qTl3VF7BvOupTR85Zc561sPEgxyUSNSvTQ9fit7DEMP7yPgvvIGm5Zfa1dOM+kOwWGNviK9uFM9ra77+OjK7lQ==",
"license": "MIT",
"peer": true,
"dependencies": {
"esbuild": "^0.25.0",
"fdir": "^6.5.0",
@@ -5599,7 +5579,6 @@
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
"license": "MIT",
"peer": true,
"engines": {
"node": ">=12"
},
@@ -96,12 +96,13 @@ export const EmptyFallback = ({
width: "100%",
}}
>
{bullets?.map((bullet: string) => (
<BulletPointCheck
text={bullet}
key={`${bullet}-${Math.random()}`}
/>
))}
{Array.isArray(bullets) &&
bullets?.map((bullet: string) => (
<BulletPointCheck
text={bullet}
key={`${bullet}-${Math.random()}`}
/>
))}
</Stack>
<Stack>
<Button
+59 -2
View File
@@ -6,9 +6,12 @@
"delete": "Delete",
"confirm": "Confirm",
"cancel": "Cancel",
"test": "Test",
"save": "Save",
"pause": "Pause",
"resume": "Resume",
"enable": "Enable",
"disable": "Disable",
"configure": "Configure",
"createNew": "Create new",
"toggleTheme": "Toggle theme",
@@ -19,7 +22,9 @@
"day": "Day",
"week": "7 days",
"month": "30 days"
}
},
"yes": "Yes",
"no": "No"
},
"dialog": {
"delete": {
@@ -104,6 +109,7 @@
"table": {
"headers": {
"name": "Name",
"active": "Active",
"type": "Type",
"status": "Status",
"statusCode": "Status code",
@@ -271,7 +277,58 @@
}
}
},
"notifications": {},
"notificationChannels": {
"infoBox": {
"title": "Notification Channels",
"description": "Configure where you want to receive notifications when monitors detect issues. Connect email, Slack, Discord, webhooks, and other channels to stay informed."
},
"fallback": {
"actionButton": "Create a channel",
"checks": [
"Alert teams about downtime or performance issues",
"Let engineers know when incidents happen",
"Keep administrators informed of system changes"
],
"title": "Notification channles are used toto:"
},
"form": {
"name": {
"title": "Channel name",
"description": "A descriptive name for the notification channel",
"optionName": "Channel name",
"placeholder": "e.g. Production Alerts"
},
"type": {
"title": "Channel type",
"description": "Select the type of notification channel to create.",
"optionType": "Type"
},
"email": {
"title": "Email configuration",
"description": "Configure the email address where notifications will be sent",
"option": "Destination email address",
"placeholder": "e.g. john@example.com"
},
"slack": {
"title": "Slack configuration",
"description": "Configure your Slack webhook URL. Create one in Slack: Settings & administration → Manage apps → Custom Integrations → Incoming Webhooks",
"option": "Webhook URL",
"placeholder": "https://hooks.slack.com/services/YOUR/WEBHOOK/URL"
},
"discord": {
"title": "Discord configuration",
"description": "Configure your Discord webhook URL. Create one in Discord: Settings & administration → Manage apps → Custom Integrations → Incoming Webhooks",
"option": "Webhook URL",
"placeholder": "https://discord.com/api/webhooks/YOUR/WEBHOOK/URL"
},
"webhook": {
"title": "Webhook configuration",
"description": "Configure the webhook URL endpoint where notifications will be sent",
"option": "Webhook URL",
"placeholder": "https://your-server.com/webhook"
}
}
},
"incidents": {},
"checks": {},
"statusPages": {}
@@ -50,7 +50,7 @@ const NotificationChannelsPage = () => {
return [
{
id: 1,
label: "Configure",
label: t("monitors.common.actions.configure"),
action: () => {
navigate(`/notification-channels/${channel._id}/configure`);
},
@@ -58,7 +58,9 @@ const NotificationChannelsPage = () => {
},
{
id: 2,
label: channel.isActive ? "Disable" : "Enable",
label: channel.isActive
? t("common.buttons.disable")
: t("common.buttons.enable"),
action: async () => {
const res = await patch(
`/notification-channels/${channel._id}/active`,
@@ -72,7 +74,11 @@ const NotificationChannelsPage = () => {
},
{
id: 7,
label: <Typography color={theme.palette.error.main}>Remove</Typography>,
label: (
<Typography color={theme.palette.error.main}>
{t("common.buttons.delete")}
</Typography>
),
action: async () => {
setSelectedChannel(channel);
},
@@ -85,16 +91,18 @@ const NotificationChannelsPage = () => {
const headers: Header<INotificationChannel>[] = [
{
id: "name",
content: "Name",
content: t("monitors.common.table.headers.name"),
render: (row) => {
return <Typography>{row?.name}</Typography>;
},
},
{
id: "active",
content: "Active",
content: t("monitors.common.table.headers.active"),
render: (row) => {
const active = row.isActive ? "Yes" : "No";
const active = row.isActive
? t("common.buttons.yes")
: t("common.buttons.no");
return <Typography>{active}</Typography>;
},
},
@@ -109,7 +117,7 @@ const NotificationChannelsPage = () => {
},
{
id: "actions",
content: t("actions"),
content: t("monitors.common.table.headers.actions"),
render: (row) => {
return <ActionsMenu items={getActions(row)} />;
},
@@ -122,19 +130,21 @@ const NotificationChannelsPage = () => {
return (
<BasePageWithStates
page="Notification Channels"
page={t("notificationChannels.fallback.title")}
bullets={
t("notifications.fallback.checks", { returnObjects: true }) as string[]
t("notificationChannels.fallback.checks", {
returnObjects: true,
}) as string[]
}
loading={isValidating}
error={error}
items={notificationChannels}
actionButtonText="Create a channel"
actionButtonText={t("notificationChannels.fallback.actionButton")}
actionLink="/notification-channels/create"
>
<InfoBox
title="Alert Destinations"
description="Configure where you want to receive alerts when monitors detect issues. Connect email, Slack, Discord, webhooks, and other channels to stay informed."
title={t("notificationChannels.infoBox.title")}
description={t("notificationChannels.infoBox.description")}
/>
<HeaderCreate
label={"Create a new notification channel"}
@@ -152,8 +162,8 @@ const NotificationChannelsPage = () => {
/>
<Dialog
title={t("createNotifications.dialogDeleteTitle")}
content={t("createNotifications.dialogDeleteContent")}
title={t("common.dialog.delete.title")}
content={t("common.dialog.delete.description")}
open={open}
onConfirm={handleConfirm}
onCancel={handleCancel}
@@ -73,8 +73,8 @@ export const NotificationChannelsForm = ({
return (
<BasePage component={"form"} onSubmit={handleSubmit(onSubmit, onError)}>
<ConfigBox
title={t("createNotifications.nameSettings.title")}
subtitle={t("createNotifications.nameSettings.description")}
title={t("notificationChannels.form.name.title")}
subtitle={t("notificationChannels.form.name.description")}
rightContent={
<Controller
name="name"
@@ -83,8 +83,8 @@ export const NotificationChannelsForm = ({
<TextInput
{...field}
type="text"
fieldLabel={t("createNotifications.nameSettings.nameLabel")}
placeholder="e.g. Production Alerts"
fieldLabel={t("notificationChannels.form.name.optionName")}
placeholder={t("notificationChannels.form.name.placeholder")}
fullWidth
error={!!errors.name}
helperText={errors.name ? errors.name.message : ""}
@@ -94,8 +94,8 @@ export const NotificationChannelsForm = ({
}
/>
<ConfigBox
title={t("createNotifications.typeSettings.title")}
subtitle={t("createNotifications.typeSettings.description")}
title={t("notificationChannels.form.type.title")}
subtitle={t("notificationChannels.form.type.description")}
rightContent={
<Controller
name="type"
@@ -105,7 +105,7 @@ export const NotificationChannelsForm = ({
return (
<Select
value={field.value}
fieldLabel={t("createNotifications.typeSettings.title")}
fieldLabel={t("notificationChannels.form.type.optionType")}
error={!!errors.type}
onChange={field.onChange}
>
@@ -125,18 +125,8 @@ export const NotificationChannelsForm = ({
}
/>
<ConfigBox
title={type ? `${type} configuration` : "Config"}
subtitle={
type === "email"
? "Configure the email address where notifications will be sent"
: type === "webhook"
? "Configure the webhook URL endpoint where notifications will be sent"
: type === "slack"
? "Configure your Slack webhook URL. Create one in Slack: Settings & administration → Manage apps → Custom Integrations → Incoming Webhooks"
: type === "discord"
? "Configure your Discord webhook URL. Create one in Discord: Server Settings → Integrations → Webhooks → New Webhook"
: "Configure notification channel settings"
}
title={t(`notificationChannels.form.${type}.title`)}
subtitle={t(`notificationChannels.form.${type}.description`)}
rightContent={
type === "email" ? (
<Controller
@@ -148,10 +138,10 @@ export const NotificationChannelsForm = ({
<TextInput
{...field}
type="text"
fieldLabel={t(
"createNotifications.emailSettings.description"
fieldLabel={t(`notificationChannels.form.${type}.option`)}
placeholder={t(
`notificationChannels.form.${type}.placeholder`
)}
placeholder="e.g. john@example.com"
fullWidth
error={!!errors.config?.emailAddress}
helperText={
@@ -169,31 +159,14 @@ export const NotificationChannelsForm = ({
control={control}
defaultValue={defaults.config.url}
render={({ field }) => {
const getPlaceholder = () => {
switch (type) {
case "slack":
return "https://hooks.slack.com/services/YOUR/WEBHOOK/URL";
case "discord":
return "https://discord.com/api/webhooks/YOUR/WEBHOOK/URL";
case "webhook":
return "https://your-server.com/webhook";
default:
return "https://example.com/webhook";
}
};
return (
<TextInput
{...field}
type="text"
fieldLabel={
type
? `${
type.charAt(0).toUpperCase() + type.slice(1)
} webhook URL`
: "URL"
}
placeholder={getPlaceholder()}
fieldLabel={t(`notificationChannels.form.${type}.option`)}
placeholder={t(
`notificationChannels.form.${type}.placeholder`
)}
fullWidth
error={!!errors.config?.url}
helperText={
@@ -217,7 +190,7 @@ export const NotificationChannelsForm = ({
onClick={handleTest}
loading={isPosting || loading}
>
Test
{t("common.buttons.test")}
</Button>
<Button
loading={isPosting || loading}
@@ -225,7 +198,7 @@ export const NotificationChannelsForm = ({
variant="contained"
color="primary"
>
{t("settingsSave")}
{t("common.buttons.save")}
</Button>
</Stack>
</BasePage>
+17 -16
View File
@@ -18,7 +18,7 @@
"got": "14.5.0",
"jsonwebtoken": "9.0.2",
"mongoose": "8.19.1",
"nodemailer": "7.0.9",
"nodemailer": "^7.0.11",
"ping": "1.0.0",
"stripe": "^20.0.0",
"super-simple-scheduler": "1.4.6",
@@ -797,7 +797,6 @@
"integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@babel/code-frame": "^7.27.1",
"@babel/generator": "^7.28.5",
@@ -2384,6 +2383,7 @@
"dev": true,
"license": "MIT",
"optional": true,
"peer": true,
"dependencies": {
"@types/node": "*",
"jest-regex-util": "30.0.1"
@@ -2685,6 +2685,7 @@
"dev": true,
"license": "MIT",
"optional": true,
"peer": true,
"dependencies": {
"@sinclair/typebox": "^0.34.0"
},
@@ -2934,6 +2935,7 @@
"dev": true,
"license": "MIT",
"optional": true,
"peer": true,
"dependencies": {
"@jest/pattern": "30.0.1",
"@jest/schemas": "30.0.5",
@@ -3069,7 +3071,8 @@
"integrity": "sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g==",
"dev": true,
"license": "MIT",
"optional": true
"optional": true,
"peer": true
},
"node_modules/@sindresorhus/is": {
"version": "7.1.1",
@@ -3837,7 +3840,6 @@
"integrity": "sha512-LuIQOcb6UmnF7C1PCFmEU1u2hmiHL43fgFQX67sN3H4Z+0Yk0Neo++mFsBjhOAuLzvlQeqAAkeDOZrJs9rzumQ==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@types/body-parser": "*",
"@types/express-serve-static-core": "^5.0.0",
@@ -3949,7 +3951,6 @@
"integrity": "sha512-CmyhGZanP88uuC5GpWU9q+fI61j2SkhO3UGMUdfYRE6Bcy0ccyzn1Rqj9YAB/ZY4kOXmNf0ocah5GtphmLMP6Q==",
"devOptional": true,
"license": "MIT",
"peer": true,
"dependencies": {
"undici-types": "~7.14.0"
}
@@ -4337,7 +4338,6 @@
}
],
"license": "MIT",
"peer": true,
"dependencies": {
"baseline-browser-mapping": "^2.8.25",
"caniuse-lite": "^1.0.30001754",
@@ -4606,6 +4606,7 @@
],
"license": "MIT",
"optional": true,
"peer": true,
"engines": {
"node": ">=8"
}
@@ -7306,6 +7307,7 @@
"dev": true,
"license": "MIT",
"optional": true,
"peer": true,
"engines": {
"node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0"
}
@@ -8337,6 +8339,7 @@
"dev": true,
"license": "MIT",
"optional": true,
"peer": true,
"dependencies": {
"@jest/types": "30.2.0",
"@types/node": "*",
@@ -8356,6 +8359,7 @@
"dev": true,
"license": "MIT",
"optional": true,
"peer": true,
"engines": {
"node": ">=12"
},
@@ -8650,12 +8654,11 @@
}
},
"node_modules/jws": {
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz",
"integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==",
"license": "MIT",
"version": "3.2.3",
"resolved": "https://registry.npmjs.org/jws/-/jws-3.2.3.tgz",
"integrity": "sha512-byiJ0FLRdLdSVSReO/U4E7RoEyOCKnEnEPMjq3HxWtvzLsV08/i5RQKsFVNkCldrCaPr2vDNAOMsfs8T/Hze7g==",
"dependencies": {
"jwa": "^1.4.1",
"jwa": "^1.4.2",
"safe-buffer": "^5.0.1"
}
},
@@ -9134,10 +9137,9 @@
"license": "MIT"
},
"node_modules/nodemailer": {
"version": "7.0.9",
"resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-7.0.9.tgz",
"integrity": "sha512-9/Qm0qXIByEP8lEV2qOqcAW7bRpL8CR9jcTwk3NBnHJNmP9fIJ86g2fgmIXqHY+nj55ZEMwWqYAT2QTDpRUYiQ==",
"license": "MIT-0",
"version": "7.0.11",
"resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-7.0.11.tgz",
"integrity": "sha512-gnXhNRE0FNhD7wPSCGhdNh46Hs6nm+uTyg+Kq0cZukNQiYdnCsoQjodNP9BQVG9XrcK/v6/MgpAPBUFyzh9pvw==",
"engines": {
"node": ">=6.0.0"
}
@@ -10582,7 +10584,6 @@
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
"dev": true,
"license": "Apache-2.0",
"peer": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
+1 -1
View File
@@ -39,7 +39,7 @@
"got": "14.5.0",
"jsonwebtoken": "9.0.2",
"mongoose": "8.19.1",
"nodemailer": "7.0.9",
"nodemailer": "^7.0.11",
"ping": "1.0.0",
"stripe": "^20.0.0",
"super-simple-scheduler": "1.4.6",