Skip to content

Commit

Permalink
Merge branch 'master' of github.com:OneUptime/oneuptime
Browse files Browse the repository at this point in the history
  • Loading branch information
simlarsen committed Jul 2, 2024
2 parents 733901a + e2eff65 commit 3861d09
Show file tree
Hide file tree
Showing 48 changed files with 22,104 additions and 1,426 deletions.
954 changes: 527 additions & 427 deletions App/FeatureSet/ApiReference/views/main/model.ejs

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions App/FeatureSet/ApiReference/views/partials/head.ejs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
applyStylesTo("h3", "mb-5 scroll-mt-24 mt-10 font-bold text-base")
applyStylesTo("p", "mb-5")
applyStylesTo("link", "text-emerald-500 hover:text-emerald-600")
applyStylesTo("model-inline-code", "rounded p-0.5 px-1 text-sm text-gray-50 bg-gray-600 border-2 border-gray-600 shadow")
applyStylesTo("inline-code", "rounded p-0.5 px-1 text-sm text-gray-500 bg-gray-100 border-2 border-gray-200")
}
Expand Down
27 changes: 27 additions & 0 deletions App/FeatureSet/BaseAPI/Index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,15 @@ import WorkflowService, {
import WorkflowVariableService, {
Service as WorkflowVariableServiceType,
} from "CommonServer/Services/WorkflowVariableService";

import ProbeOwnerTeamService, {
Service as ProbeOwnerTeamServiceType,
} from "CommonServer/Services/ProbeOwnerTeamService";

import ProbeOwnerUserService, {
Service as ProbeOwnerUserServiceType,
} from "CommonServer/Services/ProbeOwnerUserService";

import FeatureSet from "CommonServer/Types/FeatureSet";
import Express, { ExpressApplication } from "CommonServer/Utils/Express";
import Log from "Model/AnalyticsModels/Log";
Expand Down Expand Up @@ -377,6 +386,8 @@ import UserOnCallLog from "Model/Models/UserOnCallLog";
import Workflow from "Model/Models/Workflow";
import WorkflowLog from "Model/Models/WorkflowLog";
import WorkflowVariable from "Model/Models/WorkflowVariable";
import ProbeOwnerTeam from "Model/Models/ProbeOwnerTeam";
import ProbeOwnerUser from "Model/Models/ProbeOwnerUser";

const BaseAPIFeatureSet: FeatureSet = {
init: async (): Promise<void> => {
Expand Down Expand Up @@ -448,6 +459,22 @@ const BaseAPIFeatureSet: FeatureSet = {
).getRouter(),
);

app.use(
`/${APP_NAME.toLocaleLowerCase()}`,
new BaseAPI<ProbeOwnerUser, ProbeOwnerUserServiceType>(
ProbeOwnerUser,
ProbeOwnerUserService,
).getRouter(),
);

app.use(
`/${APP_NAME.toLocaleLowerCase()}`,
new BaseAPI<ProbeOwnerTeam, ProbeOwnerTeamServiceType>(
ProbeOwnerTeam,
ProbeOwnerTeamService,
).getRouter(),
);

app.use(
`/${APP_NAME.toLocaleLowerCase()}`,
new BaseAPI<MonitorSecret, MonitorSecretServiceType>(
Expand Down
5 changes: 2 additions & 3 deletions App/FeatureSet/Docs/Content/installation/docker-compose.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ If you still want to deploy OneUptime in production with docker-compose, please
- **SSL/TLS**: Set up SSL/TLS certificates. OneUptime does not support setting up SSL/TLS certificates. You need to set up SSL/TLS certificates on your own. Please see above.
- **Secrets**: Make sure you have random secrets in your `config.env` file. There are some default secrets in that file. Please replace them with random long strings.
- **Backups**: Regularly backup your databases (Clickhouse, Postgres). Redis is used as a cache and is stateless and can be safely ignored.
- **Updates**: Please regularly update OneUptime. We release updates every day. We recommend you to update the software aleast once a week if you're running in production.

### Updating OneUptime

Expand All @@ -96,6 +97,4 @@ npm run update

### Things to consider

- In our Docker setup, we employ a local logging driver. OneUptime, particularly within the probe and ingestor containers, generates a substantial amount of logs. To prevent your storage from becoming full, it's crucial to limit the logging storage in Docker. For detailed instructions on how to do this, please refer to the official Docker documentation [here](https://docs.docker.com/config/containers/logging/local/).


- In our Docker setup, we employ a local logging driver. OneUptime, particularly within the probe and ingestor containers, generates a substantial amount of logs. To prevent your storage from becoming full, it's crucial to limit the logging storage in Docker. For detailed instructions on how to do this, please refer to the official Docker documentation [here](https://docs.docker.com/config/containers/logging/local/).
1 change: 0 additions & 1 deletion App/FeatureSet/Docs/Content/probe/custom-probe.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ To run a probe, please make sure you have docker installed. You can run custom p

```
docker run --name oneuptime-probe --network host -e PROBE_KEY=<probe-key> -e PROBE_ID=<probe-id> -e ONEUPTIME_URL=https://oneuptime.com -d oneuptime/probe:release
```

If you are self hosting OneUptime, you can change `INGESTOR_URL` to your custom self hosted instance.
Expand Down
12 changes: 6 additions & 6 deletions App/FeatureSet/Notification/Services/MailService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -273,14 +273,14 @@ export default class MailService {
mail.vars["year"] = OneUptimeDate.getCurrentYear().toString();
}

mail.body = mail.templateType
? await this.compileEmailBody(mail.templateType, mail.vars)
: this.compileText(mail.body || "", mail.vars);
mail.subject = this.compileText(mail.subject, mail.vars);
try {
const emailServerType: EmailServerType = await getEmailServerType();

const emailServerType: EmailServerType = await getEmailServerType();
mail.body = mail.templateType
? await this.compileEmailBody(mail.templateType, mail.vars)
: this.compileText(mail.body || "", mail.vars);
mail.subject = this.compileText(mail.subject, mail.vars);

try {
if (
(!options || !options.emailServer) &&
emailServerType === EmailServerType.Sendgrid
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{{> Start this}}


{{> Logo this}}
{{> EmailTitle title=title}}

{{> InfoBlock info="Here are the details: "}}

{{> DetailBoxStart this }}
{{> DetailBoxField title="Probe Name:" text=probeName }}
{{> DetailBoxField title="Probe Description:" text=probeDescription }}
{{> DetailBoxField title="Probe Status:" text=probeStatus }}
{{> DetailBoxField title="Status Since:" text="" }}
{{> DetailBoxField title="" text=lastAlive }}
{{> DetailBoxField title="Project Name: " text=projectName }}
{{> DetailBoxEnd this }}


{{> InfoBlock info="You can view this probe by going to Project Settings > Probes "}}

{{> ButtonBlock buttonUrl=viewProbesLink buttonText="View Probes"}}

{{> InfoBlock info="You can also copy and paste this link:"}}
{{> InfoBlock info=viewProbesLink}}

{{> InfoBlock info="You will be notified when the status of this probe changes."}}

{{> OwnerInfo this }}
{{> UnsubscribeOwnerEmail this }}

{{> Footer this }}

{{> End this}}
28 changes: 28 additions & 0 deletions App/FeatureSet/Notification/Templates/ProbeOwnerAdded.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{{> Start this}}


{{> Logo this}}
{{> EmailTitle title=(concat "Probe: " probeName) }}

{{> InfoBlock info="You have been added as the owner of this probe."}}

{{> InfoBlock info="Here are the details: "}}

{{> DetailBoxStart this }}
{{> DetailBoxField title="Probe Name:" text=probeName }}
{{> DetailBoxField title="Probe Description: " text=probeDescription }}
{{> DetailBoxEnd this }}


{{> InfoBlock info="You can view this probe by clicking on the button below - "}}

{{> ButtonBlock buttonUrl=viewProbeLink buttonText="View on Dashboard"}}

{{> InfoBlock info="You can also copy and paste this link:"}}
{{> InfoBlock info=viewProbeLink}}

{{> InfoBlock info="You will be notified when the status of this probe changes."}}

{{> Footer this }}

{{> End this}}
4 changes: 4 additions & 0 deletions App/FeatureSet/Workers/Index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ import QueueWorker from "CommonServer/Infrastructure/QueueWorker";
import FeatureSet from "CommonServer/Types/FeatureSet";
import logger from "CommonServer/Utils/Logger";

// Probes
import "./Jobs/Probe/SendOwnerAddedNotification";
import "./Jobs/Probe/UpdateConnectionStatus";

const WorkersFeatureSet: FeatureSet = {
init: async (): Promise<void> => {
try {
Expand Down
190 changes: 190 additions & 0 deletions App/FeatureSet/Workers/Jobs/Probe/SendOwnerAddedNotification.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
import RunCron from "../../Utils/Cron";
import { CallRequestMessage } from "Common/Types/Call/CallRequest";
import LIMIT_MAX from "Common/Types/Database/LimitMax";
import Dictionary from "Common/Types/Dictionary";
import { EmailEnvelope } from "Common/Types/Email/EmailMessage";
import EmailTemplateType from "Common/Types/Email/EmailTemplateType";
import NotificationSettingEventType from "Common/Types/NotificationSetting/NotificationSettingEventType";
import ObjectID from "Common/Types/ObjectID";
import { SMSMessage } from "Common/Types/SMS/SMS";
import { EVERY_MINUTE } from "Common/Utils/CronTime";
import ProbeOwnerTeamService from "CommonServer/Services/ProbeOwnerTeamService";
import ProbeOwnerUserService from "CommonServer/Services/ProbeOwnerUserService";
import TeamMemberService from "CommonServer/Services/TeamMemberService";
import UserNotificationSettingService from "CommonServer/Services/UserNotificationSettingService";
import ProbeOwnerTeam from "Model/Models/ProbeOwnerTeam";
import ProbeOwnerUser from "Model/Models/ProbeOwnerUser";
import User from "Model/Models/User";
import Probe from "Model/Models/Probe";
import ProbeService from "CommonServer/Services/ProbeService";

RunCron(
"ProbeOwner:SendOwnerAddedEmail",
{ schedule: EVERY_MINUTE, runOnStartup: false },
async () => {
const probeOwnerTeams: Array<ProbeOwnerTeam> =
await ProbeOwnerTeamService.findBy({
query: {
isOwnerNotified: false,
},
props: {
isRoot: true,
},
limit: LIMIT_MAX,
skip: 0,
select: {
_id: true,
probeId: true,
teamId: true,
},
});

const probeOwnersMap: Dictionary<Array<User>> = {};

for (const probeOwnerTeam of probeOwnerTeams) {
const probeId: ObjectID = probeOwnerTeam.probeId!;
const teamId: ObjectID = probeOwnerTeam.teamId!;

const users: Array<User> = await TeamMemberService.getUsersInTeams([
teamId,
]);

if (probeOwnersMap[probeId.toString()] === undefined) {
probeOwnersMap[probeId.toString()] = [];
}

for (const user of users) {
(probeOwnersMap[probeId.toString()] as Array<User>).push(user);
}

// mark this as notified.
await ProbeOwnerTeamService.updateOneById({
id: probeOwnerTeam.id!,
data: {
isOwnerNotified: true,
},
props: {
isRoot: true,
},
});
}

const probeOwnerUsers: Array<ProbeOwnerUser> =
await ProbeOwnerUserService.findBy({
query: {
isOwnerNotified: false,
},
props: {
isRoot: true,
},
limit: LIMIT_MAX,
skip: 0,
select: {
_id: true,
probeId: true,
userId: true,
user: {
email: true,
name: true,
},
},
});

for (const probeOwnerUser of probeOwnerUsers) {
const probeId: ObjectID = probeOwnerUser.probeId!;
const user: User = probeOwnerUser.user!;

if (probeOwnersMap[probeId.toString()] === undefined) {
probeOwnersMap[probeId.toString()] = [];
}

(probeOwnersMap[probeId.toString()] as Array<User>).push(user);

// mark this as notified.
await ProbeOwnerUserService.updateOneById({
id: probeOwnerUser.id!,
data: {
isOwnerNotified: true,
},
props: {
isRoot: true,
},
});
}

// send email to all of these users.

for (const probeId in probeOwnersMap) {
if (!probeOwnersMap[probeId]) {
continue;
}

if ((probeOwnersMap[probeId] as Array<User>).length === 0) {
continue;
}

const users: Array<User> = probeOwnersMap[probeId] as Array<User>;

// get all scheduled events of all the projects.
const probe: Probe | null = await ProbeService.findOneById({
id: new ObjectID(probeId),
props: {
isRoot: true,
},

select: {
_id: true,
name: true,
description: true,
projectId: true,
project: {
name: true,
},
},
});

if (!probe) {
continue;
}

const vars: Dictionary<string> = {
probeName: probe.name!,
probeDescription: probe.description || "No description provided",
projectName: probe.project!.name!,
viewProbeLink: (
await ProbeService.getLinkInDashboard(probe.projectId!, probe.id!)
).toString(),
};

for (const user of users) {
const emailMessage: EmailEnvelope = {
templateType: EmailTemplateType.ProbeOwnerAdded,
vars: vars,
subject: "[Probe] Owner of " + probe.name,
};

const sms: SMSMessage = {
message: `This is a message from OneUptime. You have been added as the owner of the probe: ${probe.name!}. To unsubscribe from this notification go to User Settings in OneUptime Dashboard.`,
};

const callMessage: CallRequestMessage = {
data: [
{
sayMessage: `This is a message from OneUptime. You have been added as the owner of the probe: ${probe.name!}. To unsubscribe from this notification go to User Settings in OneUptime Dashboard. Good bye.`,
},
],
};

await UserNotificationSettingService.sendUserNotification({
userId: user.id!,
projectId: probe.projectId!,
emailEnvelope: emailMessage,
smsMessage: sms,
callRequestMessage: callMessage,
eventType:
NotificationSettingEventType.SEND_PROBE_OWNER_ADDED_NOTIFICATION,
});
}
}
},
);
Loading

0 comments on commit 3861d09

Please sign in to comment.