mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-20 02:53:42 +00:00
feat(audit-log-stream): backend rework
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
import { RawAxiosRequestHeaders } from "axios";
|
||||
|
||||
import { getConfig } from "@app/lib/config/env";
|
||||
import { request } from "@app/lib/config/request";
|
||||
import { BadRequestError } from "@app/lib/errors";
|
||||
import { blockLocalAndPrivateIpAddresses } from "@app/lib/validator";
|
||||
|
||||
import { AUDIT_LOG_STREAM_TIMEOUT } from "../../audit-log/audit-log-queue";
|
||||
import { TLogStreamFactoryStreamLog, TLogStreamFactoryValidateCredentials } from "../audit-log-stream-types";
|
||||
import { TSplunkProviderCredentials } from "./splunk-provider-types";
|
||||
|
||||
function createPayload(event: Record<string, unknown>) {
|
||||
const appCfg = getConfig();
|
||||
|
||||
return {
|
||||
time: Math.floor(Date.now() / 1000),
|
||||
host: new URL(appCfg.SITE_URL || "http://infisical").host,
|
||||
source: "infisical",
|
||||
sourcetype: "_json",
|
||||
event
|
||||
};
|
||||
}
|
||||
|
||||
async function createSplunkUrl(hostname: string) {
|
||||
let parsedHostname: string;
|
||||
try {
|
||||
parsedHostname = new URL(`https://${hostname}`).hostname;
|
||||
} catch (error) {
|
||||
throw new BadRequestError({ message: `Invalid Splunk hostname provided: ${(error as Error).message}` });
|
||||
}
|
||||
|
||||
await blockLocalAndPrivateIpAddresses(`https://${hostname}`);
|
||||
|
||||
return `https://${parsedHostname}:8088/services/collector/event`;
|
||||
}
|
||||
|
||||
export const SplunkProviderFactory = () => {
|
||||
const validateCredentials: TLogStreamFactoryValidateCredentials<TSplunkProviderCredentials> = async ({
|
||||
credentials
|
||||
}) => {
|
||||
const { hostname, token } = credentials;
|
||||
|
||||
const url = await createSplunkUrl(hostname);
|
||||
|
||||
const streamHeaders: RawAxiosRequestHeaders = {
|
||||
"Content-Type": "application/json",
|
||||
Authorization: `Splunk ${token}`
|
||||
};
|
||||
|
||||
await request
|
||||
.post(url, createPayload({ ping: "ok" }), {
|
||||
headers: streamHeaders,
|
||||
timeout: AUDIT_LOG_STREAM_TIMEOUT,
|
||||
signal: AbortSignal.timeout(AUDIT_LOG_STREAM_TIMEOUT)
|
||||
})
|
||||
.catch((err) => {
|
||||
throw new BadRequestError({ message: `Failed to connect with Splunk: ${(err as Error)?.message}` });
|
||||
});
|
||||
|
||||
return credentials;
|
||||
};
|
||||
|
||||
const streamLog: TLogStreamFactoryStreamLog<TSplunkProviderCredentials> = async ({ credentials, auditLog }) => {
|
||||
const { hostname, token } = credentials;
|
||||
|
||||
const url = await createSplunkUrl(hostname);
|
||||
|
||||
const streamHeaders: RawAxiosRequestHeaders = {
|
||||
"Content-Type": "application/json",
|
||||
Authorization: `Splunk ${token}`
|
||||
};
|
||||
|
||||
await request.post(url, createPayload(auditLog), {
|
||||
headers: streamHeaders,
|
||||
timeout: AUDIT_LOG_STREAM_TIMEOUT,
|
||||
signal: AbortSignal.timeout(AUDIT_LOG_STREAM_TIMEOUT)
|
||||
});
|
||||
};
|
||||
|
||||
return {
|
||||
validateCredentials,
|
||||
streamLog
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,8 @@
|
||||
import { LogProvider } from "../audit-log-stream-enums";
|
||||
|
||||
export const getSplunkProviderListItem = () => {
|
||||
return {
|
||||
name: "Splunk" as const,
|
||||
provider: LogProvider.Splunk as const
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,25 @@
|
||||
import { z } from "zod";
|
||||
|
||||
import { LogProvider } from "../audit-log-stream-enums";
|
||||
|
||||
export const SplunkProviderCredentialsSchema = z.object({
|
||||
hostname: z.string().url().trim().min(1).max(255),
|
||||
token: z.string().uuid().trim().min(1)
|
||||
});
|
||||
|
||||
export const SplunkProviderSchema = z.object({
|
||||
provider: z.literal(LogProvider.Splunk),
|
||||
credentials: SplunkProviderCredentialsSchema
|
||||
});
|
||||
|
||||
export const SanitizedSplunkProviderSchema = z.object({
|
||||
provider: z.literal(LogProvider.Splunk),
|
||||
credentials: SplunkProviderCredentialsSchema.pick({
|
||||
hostname: true
|
||||
})
|
||||
});
|
||||
|
||||
export const SplunkProviderListItemSchema = z.object({
|
||||
name: z.literal("Splunk"),
|
||||
provider: z.literal(LogProvider.Splunk)
|
||||
});
|
||||
@@ -0,0 +1,7 @@
|
||||
import { z } from "zod";
|
||||
|
||||
import { SplunkProviderCredentialsSchema, SplunkProviderSchema } from "./splunk-provider-schemas";
|
||||
|
||||
export type TSplunkProvider = z.infer<typeof SplunkProviderSchema>;
|
||||
|
||||
export type TSplunkProviderCredentials = z.infer<typeof SplunkProviderCredentialsSchema>;
|
||||
Reference in New Issue
Block a user