mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-04 11:26:17 +00:00
docs: add events system pages (#4294)
* feat: events docs * fix: make the conditions optional in casl check * Update backend/src/lib/api-docs/constants.ts * Update backend/src/lib/api-docs/constants.ts Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com> * Update docs/docs.json * docs: content * fix: pr changes * feat: improve docs * chore: remove recursive * fix: pr changes * fix: change * fix: pr changes * fix: pr changes * fix: change
This commit is contained in:
co-authored by
greptile-apps[bot]
parent
4e3613ac6e
commit
c1fb5d8998
@@ -13,11 +13,9 @@ const AUTH_REFRESH_INTERVAL = 60 * 1000;
|
||||
const HEART_BEAT_INTERVAL = 15 * 1000;
|
||||
|
||||
export const sseServiceFactory = (bus: TEventBusService, redis: Redis) => {
|
||||
let heartbeatInterval: NodeJS.Timeout | null = null;
|
||||
|
||||
const clients = new Set<EventStreamClient>();
|
||||
|
||||
heartbeatInterval = setInterval(() => {
|
||||
const heartbeatInterval = setInterval(() => {
|
||||
for (const client of clients) {
|
||||
if (client.stream.closed) continue;
|
||||
void client.ping();
|
||||
|
||||
@@ -66,15 +66,24 @@ export type EventStreamClient = {
|
||||
};
|
||||
|
||||
export function createEventStreamClient(redis: Redis, options: IEventStreamClientOpts): EventStreamClient {
|
||||
const rules = options.registered.map((r) => ({
|
||||
subject: options.type,
|
||||
action: "subscribe",
|
||||
conditions: {
|
||||
eventType: r.event,
|
||||
secretPath: r.conditions?.secretPath ?? "/",
|
||||
environment: r.conditions?.environmentSlug
|
||||
}
|
||||
}));
|
||||
const rules = options.registered.map((r) => {
|
||||
const secretPath = r.conditions?.secretPath;
|
||||
const hasConditions = r.conditions?.environmentSlug || r.conditions?.secretPath;
|
||||
|
||||
return {
|
||||
subject: options.type,
|
||||
action: "subscribe",
|
||||
conditions: {
|
||||
eventType: r.event,
|
||||
...(hasConditions
|
||||
? {
|
||||
environment: r.conditions?.environmentSlug ?? "",
|
||||
secretPath: { $glob: secretPath }
|
||||
}
|
||||
: {})
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
const id = `sse-${nanoid()}`;
|
||||
const control = new AbortController();
|
||||
|
||||
@@ -70,7 +70,8 @@ export enum ApiDocsTags {
|
||||
SecretScanning = "Secret Scanning",
|
||||
OidcSso = "OIDC SSO",
|
||||
SamlSso = "SAML SSO",
|
||||
LdapSso = "LDAP SSO"
|
||||
LdapSso = "LDAP SSO",
|
||||
Events = "Event Subscriptions"
|
||||
}
|
||||
|
||||
export const GROUPS = {
|
||||
@@ -2872,3 +2873,10 @@ export const LdapSso = {
|
||||
caCert: "The CA certificate to use when verifying the LDAP server certificate."
|
||||
}
|
||||
};
|
||||
|
||||
export const EventSubscriptions = {
|
||||
SUBSCRIBE_PROJECT_EVENTS: {
|
||||
projectId: "The ID of the project to subscribe to events for.",
|
||||
register: "List of events you want to subscribe to"
|
||||
}
|
||||
};
|
||||
|
||||
@@ -7,6 +7,7 @@ import { ActionProjectType, ProjectType } from "@app/db/schemas";
|
||||
import { getServerSentEventsHeaders } from "@app/ee/services/event/event-sse-stream";
|
||||
import { EventRegisterSchema } from "@app/ee/services/event/types";
|
||||
import { ProjectPermissionSecretActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission";
|
||||
import { ApiDocsTags, EventSubscriptions } from "@app/lib/api-docs";
|
||||
import { BadRequestError, ForbiddenRequestError, RateLimitError } from "@app/lib/errors";
|
||||
import { readLimit } from "@app/server/config/rateLimiter";
|
||||
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
|
||||
@@ -20,10 +21,14 @@ export const registerEventRouter = async (server: FastifyZodProvider) => {
|
||||
rateLimit: readLimit
|
||||
},
|
||||
schema: {
|
||||
hide: false,
|
||||
tags: [ApiDocsTags.Events],
|
||||
description: "Subscribe to project events",
|
||||
body: z.object({
|
||||
projectId: z.string().trim(),
|
||||
register: z.array(EventRegisterSchema).max(10)
|
||||
})
|
||||
projectId: z.string().trim().describe(EventSubscriptions.SUBSCRIBE_PROJECT_EVENTS.projectId),
|
||||
register: z.array(EventRegisterSchema).min(1).max(10)
|
||||
}),
|
||||
produces: ["text/event-stream"]
|
||||
},
|
||||
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
||||
handler: async (req, reply) => {
|
||||
@@ -75,13 +80,15 @@ export const registerEventRouter = async (server: FastifyZodProvider) => {
|
||||
}
|
||||
|
||||
req.body.register.forEach((r) => {
|
||||
const fields = {
|
||||
environment: r.conditions?.environmentSlug ?? "",
|
||||
secretPath: r.conditions?.secretPath ?? "/",
|
||||
eventType: r.event
|
||||
};
|
||||
|
||||
const allowed = info.permission.can(
|
||||
ProjectPermissionSecretActions.Subscribe,
|
||||
subject(ProjectPermissionSub.Secrets, {
|
||||
environment: r.conditions?.environmentSlug ?? "",
|
||||
secretPath: r.conditions?.secretPath ?? "/",
|
||||
eventType: r.event
|
||||
})
|
||||
subject(ProjectPermissionSub.Secrets, fields)
|
||||
);
|
||||
|
||||
if (!allowed) {
|
||||
@@ -89,9 +96,9 @@ export const registerEventRouter = async (server: FastifyZodProvider) => {
|
||||
name: "PermissionDenied",
|
||||
message: `You are not allowed to subscribe on secrets`,
|
||||
details: {
|
||||
event: r.event,
|
||||
environmentSlug: r.conditions?.environmentSlug,
|
||||
secretPath: r.conditions?.secretPath ?? "/"
|
||||
event: fields.eventType,
|
||||
environmentSlug: fields.environment,
|
||||
secretPath: fields.secretPath
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user