mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-14 09:30:09 +00:00
Merge branch 'main' into ENG-3016
This commit is contained in:
@@ -1,7 +1,9 @@
|
||||
import type { EmitterWebhookEventName } from "@octokit/webhooks/dist-types/types";
|
||||
import { PushEvent } from "@octokit/webhooks-types";
|
||||
import { Probot } from "probot";
|
||||
import { z } from "zod";
|
||||
|
||||
import { TBitbucketPushEvent } from "@app/ee/services/secret-scanning-v2/bitbucket/bitbucket-secret-scanning-types";
|
||||
import { getConfig } from "@app/lib/config/env";
|
||||
import { logger } from "@app/lib/logger";
|
||||
import { writeLimit } from "@app/server/config/rateLimiter";
|
||||
@@ -63,4 +65,52 @@ export const registerSecretScanningV2Webhooks = async (server: FastifyZodProvide
|
||||
return res.send("ok");
|
||||
}
|
||||
});
|
||||
|
||||
// bitbucket push event webhook
|
||||
server.route({
|
||||
method: "POST",
|
||||
url: "/bitbucket",
|
||||
schema: {
|
||||
querystring: z.object({
|
||||
dataSourceId: z.string().min(1, { message: "Data Source ID is required" })
|
||||
}),
|
||||
headers: z
|
||||
.object({
|
||||
"x-hub-signature": z.string().min(1, { message: "X-Hub-Signature header is required" })
|
||||
})
|
||||
.passthrough()
|
||||
},
|
||||
config: {
|
||||
rateLimit: writeLimit
|
||||
},
|
||||
handler: async (req, res) => {
|
||||
const { dataSourceId } = req.query;
|
||||
|
||||
// Verify signature
|
||||
const signature = req.headers["x-hub-signature"];
|
||||
if (!signature) {
|
||||
logger.error("Missing X-Hub-Signature header for Bitbucket webhook");
|
||||
return res.status(401).send({ message: "Unauthorized: Missing signature" });
|
||||
}
|
||||
|
||||
const expectedSignaturePrefix = "sha256=";
|
||||
if (!signature.startsWith(expectedSignaturePrefix)) {
|
||||
logger.error({ signature }, "Invalid X-Hub-Signature format for Bitbucket webhook");
|
||||
return res.status(401).send({ message: "Unauthorized: Invalid signature format" });
|
||||
}
|
||||
|
||||
const receivedSignature = signature.substring(expectedSignaturePrefix.length);
|
||||
|
||||
if (!dataSourceId) return res.status(400).send({ message: "Data Source ID is required" });
|
||||
|
||||
await server.services.secretScanningV2.bitbucket.handlePushEvent({
|
||||
...(req.body as TBitbucketPushEvent),
|
||||
dataSourceId,
|
||||
receivedSignature,
|
||||
bodyString: JSON.stringify(req.body)
|
||||
});
|
||||
|
||||
return res.send("ok");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
@@ -1911,6 +1911,7 @@ export const registerRoutes = async (
|
||||
await hsmService.startService();
|
||||
|
||||
await telemetryQueue.startTelemetryCheck();
|
||||
await telemetryQueue.startAggregatedEventsJob();
|
||||
await dailyResourceCleanUp.startCleanUp();
|
||||
await dailyExpiringPkiItemAlert.startSendingAlerts();
|
||||
await pkiSubscriberQueue.startDailyAutoRenewalJob();
|
||||
|
||||
@@ -31,6 +31,10 @@ import {
|
||||
AzureKeyVaultConnectionListItemSchema,
|
||||
SanitizedAzureKeyVaultConnectionSchema
|
||||
} from "@app/services/app-connection/azure-key-vault";
|
||||
import {
|
||||
BitbucketConnectionListItemSchema,
|
||||
SanitizedBitbucketConnectionSchema
|
||||
} from "@app/services/app-connection/bitbucket";
|
||||
import {
|
||||
CamundaConnectionListItemSchema,
|
||||
SanitizedCamundaConnectionSchema
|
||||
@@ -118,6 +122,7 @@ const SanitizedAppConnectionSchema = z.union([
|
||||
...SanitizedFlyioConnectionSchema.options,
|
||||
...SanitizedGitLabConnectionSchema.options,
|
||||
...SanitizedCloudflareConnectionSchema.options,
|
||||
...SanitizedBitbucketConnectionSchema.options,
|
||||
...SanitizedZabbixConnectionSchema.options
|
||||
]);
|
||||
|
||||
@@ -151,6 +156,7 @@ const AppConnectionOptionsSchema = z.discriminatedUnion("app", [
|
||||
FlyioConnectionListItemSchema,
|
||||
GitLabConnectionListItemSchema,
|
||||
CloudflareConnectionListItemSchema,
|
||||
BitbucketConnectionListItemSchema,
|
||||
ZabbixConnectionListItemSchema
|
||||
]);
|
||||
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
import { z } from "zod";
|
||||
|
||||
import { readLimit } from "@app/server/config/rateLimiter";
|
||||
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
|
||||
import { AppConnection } from "@app/services/app-connection/app-connection-enums";
|
||||
import {
|
||||
CreateBitbucketConnectionSchema,
|
||||
SanitizedBitbucketConnectionSchema,
|
||||
UpdateBitbucketConnectionSchema
|
||||
} from "@app/services/app-connection/bitbucket";
|
||||
import { AuthMode } from "@app/services/auth/auth-type";
|
||||
|
||||
import { registerAppConnectionEndpoints } from "./app-connection-endpoints";
|
||||
|
||||
export const registerBitbucketConnectionRouter = async (server: FastifyZodProvider) => {
|
||||
registerAppConnectionEndpoints({
|
||||
app: AppConnection.Bitbucket,
|
||||
server,
|
||||
sanitizedResponseSchema: SanitizedBitbucketConnectionSchema,
|
||||
createSchema: CreateBitbucketConnectionSchema,
|
||||
updateSchema: UpdateBitbucketConnectionSchema
|
||||
});
|
||||
|
||||
// The below endpoints are not exposed and for Infisical App use
|
||||
|
||||
server.route({
|
||||
method: "GET",
|
||||
url: `/:connectionId/workspaces`,
|
||||
config: {
|
||||
rateLimit: readLimit
|
||||
},
|
||||
schema: {
|
||||
params: z.object({
|
||||
connectionId: z.string().uuid()
|
||||
}),
|
||||
response: {
|
||||
200: z.object({
|
||||
workspaces: z.object({ slug: z.string() }).array()
|
||||
})
|
||||
}
|
||||
},
|
||||
onRequest: verifyAuth([AuthMode.JWT]),
|
||||
handler: async (req) => {
|
||||
const {
|
||||
params: { connectionId }
|
||||
} = req;
|
||||
|
||||
const workspaces = await server.services.appConnection.bitbucket.listWorkspaces(connectionId, req.permission);
|
||||
|
||||
return { workspaces };
|
||||
}
|
||||
});
|
||||
|
||||
server.route({
|
||||
method: "GET",
|
||||
url: `/:connectionId/repositories`,
|
||||
config: {
|
||||
rateLimit: readLimit
|
||||
},
|
||||
schema: {
|
||||
params: z.object({
|
||||
connectionId: z.string().uuid()
|
||||
}),
|
||||
querystring: z.object({
|
||||
workspaceSlug: z.string().min(1).max(255)
|
||||
}),
|
||||
response: {
|
||||
200: z.object({
|
||||
repositories: z.object({ slug: z.string(), full_name: z.string(), uuid: z.string() }).array()
|
||||
})
|
||||
}
|
||||
},
|
||||
onRequest: verifyAuth([AuthMode.JWT]),
|
||||
handler: async (req) => {
|
||||
const {
|
||||
params: { connectionId },
|
||||
query: { workspaceSlug }
|
||||
} = req;
|
||||
|
||||
const repositories = await server.services.appConnection.bitbucket.listRepositories(
|
||||
{ connectionId, workspaceSlug },
|
||||
req.permission
|
||||
);
|
||||
|
||||
return { repositories };
|
||||
}
|
||||
});
|
||||
};
|
||||
@@ -9,6 +9,7 @@ import { registerAzureAppConfigurationConnectionRouter } from "./azure-app-confi
|
||||
import { registerAzureClientSecretsConnectionRouter } from "./azure-client-secrets-connection-router";
|
||||
import { registerAzureDevOpsConnectionRouter } from "./azure-devops-connection-router";
|
||||
import { registerAzureKeyVaultConnectionRouter } from "./azure-key-vault-connection-router";
|
||||
import { registerBitbucketConnectionRouter } from "./bitbucket-connection-router";
|
||||
import { registerCamundaConnectionRouter } from "./camunda-connection-router";
|
||||
import { registerCloudflareConnectionRouter } from "./cloudflare-connection-router";
|
||||
import { registerDatabricksConnectionRouter } from "./databricks-connection-router";
|
||||
@@ -64,5 +65,6 @@ export const APP_CONNECTION_REGISTER_ROUTER_MAP: Record<AppConnection, (server:
|
||||
[AppConnection.Flyio]: registerFlyioConnectionRouter,
|
||||
[AppConnection.GitLab]: registerGitLabConnectionRouter,
|
||||
[AppConnection.Cloudflare]: registerCloudflareConnectionRouter,
|
||||
[AppConnection.Bitbucket]: registerBitbucketConnectionRouter,
|
||||
[AppConnection.Zabbix]: registerZabbixConnectionRouter
|
||||
};
|
||||
|
||||
@@ -732,8 +732,8 @@ export const registerDashboardRouter = async (server: FastifyZodProvider) => {
|
||||
actorOrgId: req.permission.orgId,
|
||||
projectId,
|
||||
environment,
|
||||
path: secretPath,
|
||||
search
|
||||
path: secretPath
|
||||
// search scott: removing for now because this prevents searching imported secrets which are fetched separately client side
|
||||
});
|
||||
|
||||
if (remainingLimit > 0 && totalImportCount > adjustedOffset) {
|
||||
@@ -745,7 +745,7 @@ export const registerDashboardRouter = async (server: FastifyZodProvider) => {
|
||||
projectId,
|
||||
environment,
|
||||
path: secretPath,
|
||||
search,
|
||||
// search scott: removing for now because this prevents searching imported secrets which are fetched separately client side
|
||||
limit: remainingLimit,
|
||||
offset: adjustedOffset
|
||||
});
|
||||
|
||||
@@ -2,7 +2,7 @@ import picomatch from "picomatch";
|
||||
import { z } from "zod";
|
||||
|
||||
import { SecretApprovalRequestsSchema, SecretsSchema, SecretType, ServiceTokenScopes } from "@app/db/schemas";
|
||||
import { EventType, UserAgentType } from "@app/ee/services/audit-log/audit-log-types";
|
||||
import { EventType, SecretApprovalEvent, UserAgentType } from "@app/ee/services/audit-log/audit-log-types";
|
||||
import { ApiDocsTags, RAW_SECRETS, SECRETS } from "@app/lib/api-docs";
|
||||
import { BadRequestError } from "@app/lib/errors";
|
||||
import { removeTrailingSlash } from "@app/lib/fn";
|
||||
@@ -594,6 +594,23 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
||||
secretReminderRepeatDays: req.body.secretReminderRepeatDays
|
||||
});
|
||||
if (secretOperation.type === SecretProtectionType.Approval) {
|
||||
await server.services.auditLog.createAuditLog({
|
||||
projectId: req.body.workspaceId,
|
||||
...req.auditLogInfo,
|
||||
event: {
|
||||
type: EventType.SECRET_APPROVAL_REQUEST,
|
||||
metadata: {
|
||||
committedBy: secretOperation.approval.committerUserId,
|
||||
secretApprovalRequestId: secretOperation.approval.id,
|
||||
secretApprovalRequestSlug: secretOperation.approval.slug,
|
||||
secretPath: req.body.secretPath,
|
||||
environment: req.body.environment,
|
||||
secretKey: req.params.secretName,
|
||||
eventType: SecretApprovalEvent.Create
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return { approval: secretOperation.approval };
|
||||
}
|
||||
|
||||
@@ -730,6 +747,23 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
||||
});
|
||||
|
||||
if (secretOperation.type === SecretProtectionType.Approval) {
|
||||
await server.services.auditLog.createAuditLog({
|
||||
projectId: req.body.workspaceId,
|
||||
...req.auditLogInfo,
|
||||
event: {
|
||||
type: EventType.SECRET_APPROVAL_REQUEST,
|
||||
metadata: {
|
||||
committedBy: secretOperation.approval.committerUserId,
|
||||
secretApprovalRequestId: secretOperation.approval.id,
|
||||
secretApprovalRequestSlug: secretOperation.approval.slug,
|
||||
secretPath: req.body.secretPath,
|
||||
environment: req.body.environment,
|
||||
secretKey: req.params.secretName,
|
||||
eventType: SecretApprovalEvent.Update
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return { approval: secretOperation.approval };
|
||||
}
|
||||
const { secret } = secretOperation;
|
||||
@@ -831,6 +865,23 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
||||
type: req.body.type
|
||||
});
|
||||
if (secretOperation.type === SecretProtectionType.Approval) {
|
||||
await server.services.auditLog.createAuditLog({
|
||||
projectId: req.body.workspaceId,
|
||||
...req.auditLogInfo,
|
||||
event: {
|
||||
type: EventType.SECRET_APPROVAL_REQUEST,
|
||||
metadata: {
|
||||
committedBy: secretOperation.approval.committerUserId,
|
||||
secretApprovalRequestId: secretOperation.approval.id,
|
||||
secretApprovalRequestSlug: secretOperation.approval.slug,
|
||||
secretPath: req.body.secretPath,
|
||||
environment: req.body.environment,
|
||||
secretKey: req.params.secretName,
|
||||
eventType: SecretApprovalEvent.Delete
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return { approval: secretOperation.approval };
|
||||
}
|
||||
|
||||
@@ -1165,7 +1216,10 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
||||
metadata: {
|
||||
committedBy: approval.committerUserId,
|
||||
secretApprovalRequestId: approval.id,
|
||||
secretApprovalRequestSlug: approval.slug
|
||||
secretApprovalRequestSlug: approval.slug,
|
||||
secretPath,
|
||||
environment,
|
||||
eventType: SecretApprovalEvent.Create
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -1351,7 +1405,11 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
||||
metadata: {
|
||||
committedBy: approval.committerUserId,
|
||||
secretApprovalRequestId: approval.id,
|
||||
secretApprovalRequestSlug: approval.slug
|
||||
secretApprovalRequestSlug: approval.slug,
|
||||
secretPath,
|
||||
environment,
|
||||
secretKey: req.params.secretName,
|
||||
eventType: SecretApprovalEvent.Update
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -1489,7 +1547,11 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
||||
metadata: {
|
||||
committedBy: approval.committerUserId,
|
||||
secretApprovalRequestId: approval.id,
|
||||
secretApprovalRequestSlug: approval.slug
|
||||
secretApprovalRequestSlug: approval.slug,
|
||||
secretPath,
|
||||
environment,
|
||||
secretKey: req.params.secretName,
|
||||
eventType: SecretApprovalEvent.Delete
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -1673,7 +1735,10 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
||||
metadata: {
|
||||
committedBy: approval.committerUserId,
|
||||
secretApprovalRequestId: approval.id,
|
||||
secretApprovalRequestSlug: approval.slug
|
||||
secretApprovalRequestSlug: approval.slug,
|
||||
secretPath,
|
||||
environment,
|
||||
eventType: SecretApprovalEvent.CreateMany
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -1801,7 +1866,13 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
||||
metadata: {
|
||||
committedBy: approval.committerUserId,
|
||||
secretApprovalRequestId: approval.id,
|
||||
secretApprovalRequestSlug: approval.slug
|
||||
secretApprovalRequestSlug: approval.slug,
|
||||
secretPath,
|
||||
environment,
|
||||
eventType: SecretApprovalEvent.UpdateMany,
|
||||
secrets: inputSecrets.map((secret) => ({
|
||||
secretKey: secret.secretName
|
||||
}))
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -1920,7 +1991,13 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
||||
metadata: {
|
||||
committedBy: approval.committerUserId,
|
||||
secretApprovalRequestId: approval.id,
|
||||
secretApprovalRequestSlug: approval.slug
|
||||
secretApprovalRequestSlug: approval.slug,
|
||||
secretPath,
|
||||
environment,
|
||||
secrets: inputSecrets.map((secret) => ({
|
||||
secretKey: secret.secretName
|
||||
})),
|
||||
eventType: SecretApprovalEvent.DeleteMany
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -2038,6 +2115,24 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
||||
secrets: inputSecrets
|
||||
});
|
||||
if (secretOperation.type === SecretProtectionType.Approval) {
|
||||
await server.services.auditLog.createAuditLog({
|
||||
projectId: req.body.workspaceId,
|
||||
...req.auditLogInfo,
|
||||
event: {
|
||||
type: EventType.SECRET_APPROVAL_REQUEST,
|
||||
metadata: {
|
||||
committedBy: secretOperation.approval.committerUserId,
|
||||
secretApprovalRequestId: secretOperation.approval.id,
|
||||
secretApprovalRequestSlug: secretOperation.approval.slug,
|
||||
secretPath,
|
||||
environment,
|
||||
secrets: inputSecrets.map((secret) => ({
|
||||
secretKey: secret.secretKey
|
||||
})),
|
||||
eventType: SecretApprovalEvent.CreateMany
|
||||
}
|
||||
}
|
||||
});
|
||||
return { approval: secretOperation.approval };
|
||||
}
|
||||
const { secrets } = secretOperation;
|
||||
@@ -2170,6 +2265,25 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
||||
mode: req.body.mode
|
||||
});
|
||||
if (secretOperation.type === SecretProtectionType.Approval) {
|
||||
await server.services.auditLog.createAuditLog({
|
||||
projectId: req.body.workspaceId,
|
||||
...req.auditLogInfo,
|
||||
event: {
|
||||
type: EventType.SECRET_APPROVAL_REQUEST,
|
||||
metadata: {
|
||||
committedBy: secretOperation.approval.committerUserId,
|
||||
secretApprovalRequestId: secretOperation.approval.id,
|
||||
secretApprovalRequestSlug: secretOperation.approval.slug,
|
||||
secretPath,
|
||||
environment,
|
||||
secrets: inputSecrets.map((secret) => ({
|
||||
secretKey: secret.secretKey,
|
||||
secretPath: secret.secretPath
|
||||
})),
|
||||
eventType: SecretApprovalEvent.UpdateMany
|
||||
}
|
||||
}
|
||||
});
|
||||
return { approval: secretOperation.approval };
|
||||
}
|
||||
const { secrets } = secretOperation;
|
||||
@@ -2298,6 +2412,25 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
||||
secrets: inputSecrets
|
||||
});
|
||||
if (secretOperation.type === SecretProtectionType.Approval) {
|
||||
await server.services.auditLog.createAuditLog({
|
||||
projectId: req.body.workspaceId,
|
||||
...req.auditLogInfo,
|
||||
event: {
|
||||
type: EventType.SECRET_APPROVAL_REQUEST,
|
||||
metadata: {
|
||||
committedBy: secretOperation.approval.committerUserId,
|
||||
secretApprovalRequestId: secretOperation.approval.id,
|
||||
secretApprovalRequestSlug: secretOperation.approval.slug,
|
||||
secretPath,
|
||||
environment,
|
||||
secrets: inputSecrets.map((secret) => ({
|
||||
secretKey: secret.secretKey
|
||||
})),
|
||||
eventType: SecretApprovalEvent.DeleteMany
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return { approval: secretOperation.approval };
|
||||
}
|
||||
const { secrets } = secretOperation;
|
||||
|
||||
Reference in New Issue
Block a user