mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-09-22 13:39:35 +00:00
feat(infisical-pg): fixed bugs in integrations and self hosted license failure
This commit is contained in:
@@ -85,7 +85,11 @@ export const licenseServiceFactory = ({
|
|||||||
logger.info(`Instance type: ${InstanceType.EnterpriseOnPrem}`);
|
logger.info(`Instance type: ${InstanceType.EnterpriseOnPrem}`);
|
||||||
isValidLicense = true;
|
isValidLicense = true;
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
// this means this is self hosted oss version
|
||||||
|
// else it would reach catch statement
|
||||||
|
isValidLicense = true;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
logger.error(error);
|
logger.error(error);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import {
|
|||||||
import { TSnapshotDalFactory } from "./snapshot-dal";
|
import { TSnapshotDalFactory } from "./snapshot-dal";
|
||||||
import { TSnapshotFolderDalFactory } from "./snapshot-folder-dal";
|
import { TSnapshotFolderDalFactory } from "./snapshot-folder-dal";
|
||||||
import { TSnapshotSecretDalFactory } from "./snapshot-secret-dal";
|
import { TSnapshotSecretDalFactory } from "./snapshot-secret-dal";
|
||||||
|
import { logger } from "@app/lib/logger";
|
||||||
|
|
||||||
type TSecretSnapshotServiceFactoryDep = {
|
type TSecretSnapshotServiceFactoryDep = {
|
||||||
snapshotDal: TSnapshotDalFactory;
|
snapshotDal: TSnapshotDalFactory;
|
||||||
@@ -112,44 +113,50 @@ export const secretSnapshotServiceFactory = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const performSnapshot = async (folderId: string) => {
|
const performSnapshot = async (folderId: string) => {
|
||||||
if (!licenseService.isValidLicense)
|
try {
|
||||||
throw new InternalServerError({ message: "Invalid license" });
|
if (!licenseService.isValidLicense)
|
||||||
|
throw new InternalServerError({ message: "Invalid license" });
|
||||||
|
|
||||||
const snapshot = await snapshotDal.transaction(async (tx) => {
|
const snapshot = await snapshotDal.transaction(async (tx) => {
|
||||||
const folder = await folderDal.findById(folderId, tx);
|
const folder = await folderDal.findById(folderId, tx);
|
||||||
if (!folder) throw new BadRequestError({ message: "Folder not found" });
|
if (!folder) throw new BadRequestError({ message: "Folder not found" });
|
||||||
|
|
||||||
const secretVersions = await secretVersionDal.findLatestVersionByFolderId(folderId, tx);
|
const secretVersions = await secretVersionDal.findLatestVersionByFolderId(folderId, tx);
|
||||||
const folderVersions = await folderVersionDal.findLatestVersionByFolderId(folderId, tx);
|
const folderVersions = await folderVersionDal.findLatestVersionByFolderId(folderId, tx);
|
||||||
const newSnapshot = await snapshotDal.create(
|
const newSnapshot = await snapshotDal.create(
|
||||||
{
|
{
|
||||||
folderId,
|
folderId,
|
||||||
envId: folder.environment.envId,
|
envId: folder.environment.envId,
|
||||||
parentFolderId: folder.parentId
|
parentFolderId: folder.parentId
|
||||||
},
|
},
|
||||||
tx
|
tx
|
||||||
);
|
);
|
||||||
const snapshotSecrets = await snapshotSecretDal.insertMany(
|
const snapshotSecrets = await snapshotSecretDal.insertMany(
|
||||||
secretVersions.map(({ id }) => ({
|
secretVersions.map(({ id }) => ({
|
||||||
secretVersionId: id,
|
secretVersionId: id,
|
||||||
envId: folder.environment.envId,
|
envId: folder.environment.envId,
|
||||||
snapshotId: newSnapshot.id
|
snapshotId: newSnapshot.id
|
||||||
})),
|
})),
|
||||||
tx
|
tx
|
||||||
);
|
);
|
||||||
const snapshotFolders = await snapshotFolderDal.insertMany(
|
const snapshotFolders = await snapshotFolderDal.insertMany(
|
||||||
folderVersions.map(({ id }) => ({
|
folderVersions.map(({ id }) => ({
|
||||||
folderVersionId: id,
|
folderVersionId: id,
|
||||||
envId: folder.environment.envId,
|
envId: folder.environment.envId,
|
||||||
snapshotId: newSnapshot.id
|
snapshotId: newSnapshot.id
|
||||||
})),
|
})),
|
||||||
tx
|
tx
|
||||||
);
|
);
|
||||||
|
|
||||||
return { ...newSnapshot, secrets: snapshotSecrets, folder: snapshotFolders };
|
return { ...newSnapshot, secrets: snapshotSecrets, folder: snapshotFolders };
|
||||||
});
|
});
|
||||||
|
|
||||||
return snapshot;
|
return snapshot;
|
||||||
|
} catch (error) {
|
||||||
|
// this to avoid snapshot errors
|
||||||
|
logger.error("Failed to perform snasphot");
|
||||||
|
logger.error(error);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const rollbackSnapshot = async ({ id: snapshotId, actor, actorId }: TRollbackSnapshotDTO) => {
|
const rollbackSnapshot = async ({ id: snapshotId, actor, actorId }: TRollbackSnapshotDTO) => {
|
||||||
|
|||||||
@@ -330,7 +330,7 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
|
|||||||
},
|
},
|
||||||
onRequest: verifyAuth([AuthMode.JWT]),
|
onRequest: verifyAuth([AuthMode.JWT]),
|
||||||
handler: async (req) => {
|
handler: async (req) => {
|
||||||
const authorizations = await server.services.integration.listIntegrationByProject({
|
const authorizations = await server.services.integrationAuth.listIntegrationAuthByProjectId({
|
||||||
actorId: req.permission.id,
|
actorId: req.permission.id,
|
||||||
actor: req.permission.type,
|
actor: req.permission.type,
|
||||||
projectId: req.params.workspaceId
|
projectId: req.params.workspaceId
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ export const registerSsoRouter = async (server: FastifyZodProvider) => {
|
|||||||
await server.register(fastifySession, { secret: appCfg.COOKIE_SECRET_SIGN_KEY });
|
await server.register(fastifySession, { secret: appCfg.COOKIE_SECRET_SIGN_KEY });
|
||||||
await server.register(passport.initialize());
|
await server.register(passport.initialize());
|
||||||
await server.register(passport.secureSession());
|
await server.register(passport.secureSession());
|
||||||
|
|
||||||
// passport oauth strategy for Google
|
// passport oauth strategy for Google
|
||||||
const isGoogleOauthActive = Boolean(
|
const isGoogleOauthActive = Boolean(
|
||||||
appCfg.CLIENT_ID_GOOGLE_LOGIN && appCfg.CLIENT_SECRET_GOOGLE_LOGIN
|
appCfg.CLIENT_ID_GOOGLE_LOGIN && appCfg.CLIENT_SECRET_GOOGLE_LOGIN
|
||||||
@@ -123,7 +122,7 @@ export const registerSsoRouter = async (server: FastifyZodProvider) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
server.route({
|
server.route({
|
||||||
url: "/sso/redirect/google",
|
url: "/redirect/google",
|
||||||
method: "GET",
|
method: "GET",
|
||||||
schema: {
|
schema: {
|
||||||
querystring: z.object({
|
querystring: z.object({
|
||||||
@@ -144,7 +143,7 @@ export const registerSsoRouter = async (server: FastifyZodProvider) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
server.route({
|
server.route({
|
||||||
url: "/sso/google",
|
url: "/google",
|
||||||
method: "GET",
|
method: "GET",
|
||||||
preValidation: passport.authenticate("google", {
|
preValidation: passport.authenticate("google", {
|
||||||
session: false,
|
session: false,
|
||||||
@@ -169,7 +168,7 @@ export const registerSsoRouter = async (server: FastifyZodProvider) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
server.route({
|
server.route({
|
||||||
url: "/sso/redirect/github",
|
url: "/redirect/github",
|
||||||
method: "GET",
|
method: "GET",
|
||||||
schema: {
|
schema: {
|
||||||
querystring: z.object({
|
querystring: z.object({
|
||||||
@@ -189,7 +188,7 @@ export const registerSsoRouter = async (server: FastifyZodProvider) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
server.route({
|
server.route({
|
||||||
url: "/sso/github",
|
url: "/github",
|
||||||
method: "GET",
|
method: "GET",
|
||||||
preValidation: passport.authenticate("github", {
|
preValidation: passport.authenticate("github", {
|
||||||
session: false,
|
session: false,
|
||||||
@@ -214,7 +213,7 @@ export const registerSsoRouter = async (server: FastifyZodProvider) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
server.route({
|
server.route({
|
||||||
url: "/sso/redirect/gitlab",
|
url: "/redirect/gitlab",
|
||||||
method: "GET",
|
method: "GET",
|
||||||
schema: {
|
schema: {
|
||||||
querystring: z.object({
|
querystring: z.object({
|
||||||
@@ -234,7 +233,7 @@ export const registerSsoRouter = async (server: FastifyZodProvider) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
server.route({
|
server.route({
|
||||||
url: "/sso/gitlab",
|
url: "/gitlab",
|
||||||
method: "GET",
|
method: "GET",
|
||||||
preValidation: passport.authenticate("gitlab", {
|
preValidation: passport.authenticate("gitlab", {
|
||||||
session: false,
|
session: false,
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ export const getIntegrationOptions = async () => {
|
|||||||
isAvailable: true,
|
isAvailable: true,
|
||||||
type: "oauth",
|
type: "oauth",
|
||||||
clientId: "",
|
clientId: "",
|
||||||
clientSlug: appCfg.CLIENT_ID_VERCEL,
|
clientSlug: appCfg.CLIENT_SLUG_VERCEL,
|
||||||
docsLink: ""
|
docsLink: ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -120,7 +120,7 @@ export const getIntegrationOptions = async () => {
|
|||||||
image: "GitHub.png",
|
image: "GitHub.png",
|
||||||
isAvailable: true,
|
isAvailable: true,
|
||||||
type: "oauth",
|
type: "oauth",
|
||||||
clientId: appCfg.CLIENT_ID_BITBUCKET,
|
clientId: appCfg.CLIENT_ID_GITHUB,
|
||||||
docsLink: ""
|
docsLink: ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -50,7 +50,9 @@ export const integrationDalFactory = (db: TDbClient) => {
|
|||||||
|
|
||||||
const findById = async (id: string, tx?: Knex) => {
|
const findById = async (id: string, tx?: Knex) => {
|
||||||
try {
|
try {
|
||||||
const doc = await integrationFindQuery(tx || db, { id }).first();
|
const doc = await integrationFindQuery(tx || db, {
|
||||||
|
[`${TableName.Integration}.id` as "id"]: id
|
||||||
|
}).first();
|
||||||
if (!doc) return;
|
if (!doc) return;
|
||||||
|
|
||||||
const { envName: name, envSlug: slug, envId, ...el } = doc;
|
const { envName: name, envSlug: slug, envId, ...el } = doc;
|
||||||
|
|||||||
@@ -159,7 +159,6 @@ export const secretQueueFactory = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
queueService.start(QueueName.IntegrationSync, async (job) => {
|
queueService.start(QueueName.IntegrationSync, async (job) => {
|
||||||
logger.info("Secret integration sync started", job.data, job.id);
|
|
||||||
const { environment, projectId, secretPath } = job.data;
|
const { environment, projectId, secretPath } = job.data;
|
||||||
const folder = await folderDal.findBySecretPath(projectId, environment, secretPath);
|
const folder = await folderDal.findBySecretPath(projectId, environment, secretPath);
|
||||||
if (!folder) {
|
if (!folder) {
|
||||||
@@ -173,6 +172,8 @@ export const secretQueueFactory = ({
|
|||||||
isActive && isSamePath(secretPath, integrationSecPath)
|
isActive && isSamePath(secretPath, integrationSecPath)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (!integrations.length) return;
|
||||||
|
logger.info("Secret integration sync started", job.data, job.id);
|
||||||
for (const integration of toBeSyncedIntegrations) {
|
for (const integration of toBeSyncedIntegrations) {
|
||||||
const integrationAuth = {
|
const integrationAuth = {
|
||||||
...integration.integrationAuth,
|
...integration.integrationAuth,
|
||||||
@@ -222,9 +223,7 @@ export const secretQueueFactory = ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
queueService.start(QueueName.SecretWebhook, async (job) => {
|
queueService.start(QueueName.SecretWebhook, async (job) => {
|
||||||
logger.info("Secret webhook job started", job.data, job.id);
|
|
||||||
await fnTriggerWebhook({ ...job.data, projectEnvDal, webhookDal });
|
await fnTriggerWebhook({ ...job.data, projectEnvDal, webhookDal });
|
||||||
logger.info("Secret webhook job ended", job.id);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return { syncSecrets };
|
return { syncSecrets };
|
||||||
|
|||||||
@@ -569,7 +569,7 @@ export const secretServiceFactory = ({
|
|||||||
secretDal,
|
secretDal,
|
||||||
folderDal
|
folderDal
|
||||||
});
|
});
|
||||||
for (let i = importedSecrets.length; i >= 0; i -= 1) {
|
for (let i = importedSecrets.length - 1; i >= 0; i -= 1) {
|
||||||
for (let j = 0; j < importedSecrets[i].secrets.length; j += 1) {
|
for (let j = 0; j < importedSecrets[i].secrets.length; j += 1) {
|
||||||
if (secretBlindIndex === importedSecrets[i].secrets[j].secretBlindIndex) {
|
if (secretBlindIndex === importedSecrets[i].secrets[j].secretBlindIndex) {
|
||||||
return importedSecrets[i].secrets[j];
|
return importedSecrets[i].secrets[j];
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import { BadRequestError } from "@app/lib/errors";
|
|||||||
|
|
||||||
import { TProjectEnvDalFactory } from "../project-env/project-env-dal";
|
import { TProjectEnvDalFactory } from "../project-env/project-env-dal";
|
||||||
import { TWebhookDalFactory } from "./webhook-dal";
|
import { TWebhookDalFactory } from "./webhook-dal";
|
||||||
|
import { logger } from "@app/lib/logger";
|
||||||
|
|
||||||
const WEBHOOK_TRIGGER_TIMEOUT = 15 * 1000;
|
const WEBHOOK_TRIGGER_TIMEOUT = 15 * 1000;
|
||||||
export const triggerWebhookRequest = async (
|
export const triggerWebhookRequest = async (
|
||||||
@@ -93,6 +94,7 @@ export const fnTriggerWebhook = async ({
|
|||||||
!isDisabled && picomatch.isMatch(secretPath, hookSecretPath, { strictSlashes: false })
|
!isDisabled && picomatch.isMatch(secretPath, hookSecretPath, { strictSlashes: false })
|
||||||
);
|
);
|
||||||
if (!toBeTriggeredHooks.length) return;
|
if (!toBeTriggeredHooks.length) return;
|
||||||
|
logger.info("Secret webhook job started", { environment, secretPath, projectId });
|
||||||
const webhooksTriggered = await Promise.allSettled(
|
const webhooksTriggered = await Promise.allSettled(
|
||||||
toBeTriggeredHooks.map((hook) =>
|
toBeTriggeredHooks.map((hook) =>
|
||||||
triggerWebhookRequest(
|
triggerWebhookRequest(
|
||||||
@@ -133,4 +135,5 @@ export const fnTriggerWebhook = async ({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
logger.info("Secret webhook job ended", { environment, secretPath, projectId });
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user