diff --git a/backend/src/ee/services/secret-scanning/secret-scanning-service.ts b/backend/src/ee/services/secret-scanning/secret-scanning-service.ts index 9b78da3af..ef511deb8 100644 --- a/backend/src/ee/services/secret-scanning/secret-scanning-service.ts +++ b/backend/src/ee/services/secret-scanning/secret-scanning-service.ts @@ -90,15 +90,17 @@ export const secretScanningServiceFactory = ({ const { data: { repositories } } = await octokit.apps.listReposAccessibleToInstallation(); - await Promise.all( - repositories.map(({ id, full_name }) => - secretScanningQueue.startFullRepoScan({ - organizationId: session.orgId, - installationId, - repository: { id, fullName: full_name } - }) - ) - ); + if (!appCfg.DISABLE_SECRET_SCANNING) { + await Promise.all( + repositories.map(({ id, full_name }) => + secretScanningQueue.startFullRepoScan({ + organizationId: session.orgId, + installationId, + repository: { id, fullName: full_name } + }) + ) + ); + } return { installatedApp }; }; @@ -151,6 +153,7 @@ export const secretScanningServiceFactory = ({ }; const handleRepoPushEvent = async (payload: WebhookEventMap["push"]) => { + const appCfg = getConfig(); const { commits, repository, installation, pusher } = payload; if (!commits || !repository || !installation || !pusher) { return; @@ -161,13 +164,15 @@ export const secretScanningServiceFactory = ({ }); if (!installationLink) return; - await secretScanningQueue.startPushEventScan({ - commits, - pusher: { name: pusher.name, email: pusher.email }, - repository: { fullName: repository.full_name, id: repository.id }, - organizationId: installationLink.orgId, - installationId: String(installation?.id) - }); + if (!appCfg.DISABLE_SECRET_SCANNING) { + await secretScanningQueue.startPushEventScan({ + commits, + pusher: { name: pusher.name, email: pusher.email }, + repository: { fullName: repository.full_name, id: repository.id }, + organizationId: installationLink.orgId, + installationId: String(installation?.id) + }); + } }; const handleRepoDeleteEvent = async (installationId: string, repositoryIds: string[]) => { diff --git a/backend/src/lib/config/env.ts b/backend/src/lib/config/env.ts index f9bbb1b46..6ae8bf02d 100644 --- a/backend/src/lib/config/env.ts +++ b/backend/src/lib/config/env.ts @@ -13,6 +13,10 @@ const zodStrBool = z const envSchema = z .object({ PORT: z.coerce.number().default(4000), + DISABLE_SECRET_SCANNING: z + .enum(["true", "false"]) + .default("false") + .transform((el) => el === "true"), REDIS_URL: zpStr(z.string()), HOST: zpStr(z.string().default("localhost")), DB_CONNECTION_URI: zpStr(z.string().describe("Postgres database connection string")).default( diff --git a/backend/src/server/routes/v1/admin-router.ts b/backend/src/server/routes/v1/admin-router.ts index 4882411d8..572409d9b 100644 --- a/backend/src/server/routes/v1/admin-router.ts +++ b/backend/src/server/routes/v1/admin-router.ts @@ -20,16 +20,23 @@ export const registerAdminRouter = async (server: FastifyZodProvider) => { schema: { response: { 200: z.object({ - config: SuperAdminSchema.omit({ createdAt: true, updatedAt: true }).merge( - z.object({ isMigrationModeOn: z.boolean() }) - ) + config: SuperAdminSchema.omit({ createdAt: true, updatedAt: true }).extend({ + isMigrationModeOn: z.boolean(), + isSecretScanningDisabled: z.boolean() + }) }) } }, handler: async () => { const config = await getServerCfg(); const serverEnvs = getConfig(); - return { config: { ...config, isMigrationModeOn: serverEnvs.MAINTENANCE_MODE } }; + return { + config: { + ...config, + isMigrationModeOn: serverEnvs.MAINTENANCE_MODE, + isSecretScanningDisabled: serverEnvs.DISABLE_SECRET_SCANNING + } + }; } }); diff --git a/frontend/src/components/v2/NoticeBanner/NoticeBanner.tsx b/frontend/src/components/v2/NoticeBanner/NoticeBanner.tsx new file mode 100644 index 000000000..cf32427a3 --- /dev/null +++ b/frontend/src/components/v2/NoticeBanner/NoticeBanner.tsx @@ -0,0 +1,26 @@ +import { ReactNode } from "react"; +import { faWarning, IconDefinition } from "@fortawesome/free-solid-svg-icons"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { twMerge } from "tailwind-merge"; + +type Props = { + icon?: IconDefinition; + title: string; + children: ReactNode; + className?: string; +}; + +export const NoticeBanner = ({ icon = faWarning, title, children, className }: Props) => ( +