oneuptime/Ingestor/Utils/Monitor.ts
Simon Larsen 5a12e70742
refactor: Update Encryption.ts to use Utf8 encoding for decryption
This code change updates the Encryption.ts file to use the Utf8 encoding for decryption in the `decrypt` method. Previously, it was using the default encoding, which could lead to incorrect results for certain inputs. This update ensures the correct decoding of the encrypted text and improves the reliability of the decryption process.
2024-05-29 13:20:56 +01:00

188 lines
6.6 KiB
TypeScript

import Hostname from 'Common/Types/API/Hostname';
import URL from 'Common/Types/API/URL';
import { LIMIT_PER_PROJECT } from 'Common/Types/Database/LimitMax';
import Dictionary from 'Common/Types/Dictionary';
import { PromiseVoidFunction } from 'Common/Types/FunctionTypes';
import IP from 'Common/Types/IP/IP';
import { JSONObject } from 'Common/Types/JSON';
import JSONFunctions from 'Common/Types/JSONFunctions';
import MonitorType from 'Common/Types/Monitor/MonitorType';
import MonitorSecretService from 'CommonServer/Services/MonitorSecretService';
import VMUtil from 'CommonServer/Utils/VM/VMAPI';
import Monitor from 'Model/Models/Monitor';
import MonitorSecret from 'Model/Models/MonitorSecret';
export default class MonitorUtil {
public static async populateSecrets(monitor: Monitor): Promise<Monitor> {
const isSecretsLoaded: boolean = false;
let monitorSecrets: MonitorSecret[] = [];
const loadSecrets: PromiseVoidFunction = async (): Promise<void> => {
if (isSecretsLoaded) {
return;
}
if (!monitor.id) {
return;
}
const secrets: Array<MonitorSecret> =
await MonitorSecretService.findBy({
query: {
monitors: [monitor.id] as any,
},
select: {
secretValue: true,
name: true,
},
limit: LIMIT_PER_PROJECT,
skip: 0,
props: {
isRoot: true,
},
});
monitorSecrets = secrets;
};
if (!monitor.monitorSteps) {
return monitor;
}
if (monitor.monitorType === MonitorType.API) {
for (const monitorStep of monitor.monitorSteps?.data
?.monitorStepsInstanceArray || []) {
if (
monitorStep.data?.requestHeaders &&
this.hasSecrets(
JSONFunctions.toString(monitorStep.data.requestHeaders)
)
) {
await loadSecrets();
monitorStep.data.requestHeaders =
(await MonitorUtil.fillSecretsInStringOrJSON({
secrets: monitorSecrets,
populateSecretsIn: monitorStep.data.requestHeaders,
})) as Dictionary<string>;
} else if (
monitorStep.data?.requestBody &&
this.hasSecrets(
JSONFunctions.toString(monitorStep.data.requestBody)
)
) {
await loadSecrets();
monitorStep.data.requestBody =
(await MonitorUtil.fillSecretsInStringOrJSON({
secrets: monitorSecrets,
populateSecretsIn: monitorStep.data.requestBody,
})) as string;
}
}
}
if (
monitor.monitorType === MonitorType.API ||
monitor.monitorType === MonitorType.IP ||
monitor.monitorType === MonitorType.Ping ||
monitor.monitorType === MonitorType.Port ||
monitor.monitorType === MonitorType.Website ||
monitor.monitorType === MonitorType.SSLCertificate
) {
for (const monitorStep of monitor.monitorSteps?.data
?.monitorStepsInstanceArray || []) {
if (
monitorStep.data?.monitorDestination &&
this.hasSecrets(
JSONFunctions.toString(
monitorStep.data.monitorDestination
)
)
) {
// replace secret in monitorDestination.
await loadSecrets();
monitorStep.data.monitorDestination =
(await MonitorUtil.fillSecretsInStringOrJSON({
secrets: monitorSecrets,
populateSecretsIn:
monitorStep.data.monitorDestination,
})) as URL | Hostname | IP;
}
}
}
if (
monitor.monitorType === MonitorType.SyntheticMonitor ||
monitor.monitorType === MonitorType.CustomJavaScriptCode
) {
for (const monitorStep of monitor.monitorSteps?.data
?.monitorStepsInstanceArray || []) {
if (
monitorStep.data?.customCode &&
this.hasSecrets(
JSONFunctions.toString(monitorStep.data.customCode)
)
) {
// replace secret in script
await loadSecrets();
monitorStep.data.customCode =
(await MonitorUtil.fillSecretsInStringOrJSON({
secrets: monitorSecrets,
populateSecretsIn: monitorStep.data.customCode,
})) as string;
}
}
}
return monitor;
}
private static hasSecrets(prepopulatedString: string): boolean {
return prepopulatedString.includes('monitorSecrets.');
}
private static async fillSecretsInStringOrJSON(data: {
secrets: MonitorSecret[];
populateSecretsIn: string | JSONObject | URL | Hostname | IP;
}): Promise<string | JSONObject | URL | Hostname | IP> {
// get all secrets for this monitor.
const secrets: MonitorSecret[] = data.secrets;
if (secrets.length === 0) {
return data.populateSecretsIn;
}
// replace all secrets in the populateSecretsIn
const storageMap: JSONObject = {
monitorSecrets: {},
};
for (const monitorSecret of secrets) {
if (!monitorSecret.name) {
continue;
}
if (!monitorSecret.secretValue) {
continue;
}
(storageMap['monitorSecrets'] as JSONObject)[
monitorSecret.name as string
] = monitorSecret.secretValue;
}
const isValueJSON: boolean = typeof data.populateSecretsIn === 'object';
return VMUtil.replaceValueInPlace(
storageMap,
data.populateSecretsIn as string,
isValueJSON
);
}
}