mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-04 23:26:20 +00:00
feat(infisical-pg): resolved multi integration auth and ip v6 support in ua
This commit is contained in:
@@ -88,7 +88,9 @@ export const ormify = <DbOps extends object, Tname extends keyof Tables>(
|
|||||||
},
|
},
|
||||||
create: async (data: Tables[Tname]["insert"], tx?: Knex) => {
|
create: async (data: Tables[Tname]["insert"], tx?: Knex) => {
|
||||||
try {
|
try {
|
||||||
const [res] = await (tx || db)(tableName).insert(data).returning("*");
|
const [res] = await (tx || db)(tableName)
|
||||||
|
.insert(data as any)
|
||||||
|
.returning("*");
|
||||||
return res;
|
return res;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw new DatabaseError({ error, name: "Create" });
|
throw new DatabaseError({ error, name: "Create" });
|
||||||
|
|||||||
@@ -392,7 +392,8 @@ export const registerRoutes = async (
|
|||||||
permissionService,
|
permissionService,
|
||||||
folderDal,
|
folderDal,
|
||||||
integrationDal,
|
integrationDal,
|
||||||
integrationAuthDal
|
integrationAuthDal,
|
||||||
|
secretQueueService
|
||||||
});
|
});
|
||||||
const serviceTokenService = serviceTokenServiceFactory({
|
const serviceTokenService = serviceTokenServiceFactory({
|
||||||
projectEnvDal,
|
projectEnvDal,
|
||||||
|
|||||||
@@ -81,14 +81,14 @@ export const registerIdentityUaRouter = async (server: FastifyZodProvider) => {
|
|||||||
})
|
})
|
||||||
.array()
|
.array()
|
||||||
.min(1)
|
.min(1)
|
||||||
.default([{ ipAddress: "0.0.0.0/0" }]),
|
.default([{ ipAddress: "0.0.0.0/0" }, { ipAddress: "::/0" }]),
|
||||||
accessTokenTrustedIps: z
|
accessTokenTrustedIps: z
|
||||||
.object({
|
.object({
|
||||||
ipAddress: z.string().trim()
|
ipAddress: z.string().trim()
|
||||||
})
|
})
|
||||||
.array()
|
.array()
|
||||||
.min(1)
|
.min(1)
|
||||||
.default([{ ipAddress: "0.0.0.0/0" }]),
|
.default([{ ipAddress: "0.0.0.0/0" }, { ipAddress: "::/0" }]),
|
||||||
accessTokenTTL: z
|
accessTokenTTL: z
|
||||||
.number()
|
.number()
|
||||||
.int()
|
.int()
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ export const tokenServiceFactory = ({ tokenDal, userDal }: TAuthTokenServiceFact
|
|||||||
const newToken = await tokenDal.create(
|
const newToken = await tokenDal.create(
|
||||||
{
|
{
|
||||||
tokenHash,
|
tokenHash,
|
||||||
expiresAt: tkCfg.expiresAt.toUTCString(),
|
expiresAt: tkCfg.expiresAt,
|
||||||
type,
|
type,
|
||||||
userId,
|
userId,
|
||||||
orgId,
|
orgId,
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import { TPermissionServiceFactory } from "@app/ee/services/permission/permissio
|
|||||||
import { isAtLeastAsPrivileged } from "@app/lib/casl";
|
import { isAtLeastAsPrivileged } from "@app/lib/casl";
|
||||||
import { getConfig } from "@app/lib/config/env";
|
import { getConfig } from "@app/lib/config/env";
|
||||||
import { BadRequestError, ForbiddenRequestError, UnauthorizedError } from "@app/lib/errors";
|
import { BadRequestError, ForbiddenRequestError, UnauthorizedError } from "@app/lib/errors";
|
||||||
import { checkIPAgainstBlocklist, extractIPDetails, isValidIpOrCidr,TIp } from "@app/lib/ip";
|
import { checkIPAgainstBlocklist, extractIPDetails, isValidIpOrCidr, TIp } from "@app/lib/ip";
|
||||||
|
|
||||||
import { ActorType, AuthTokenType } from "../auth/auth-type";
|
import { ActorType, AuthTokenType } from "../auth/auth-type";
|
||||||
import { TIdentityDalFactory } from "../identity/identity-dal";
|
import { TIdentityDalFactory } from "../identity/identity-dal";
|
||||||
@@ -176,7 +176,11 @@ export const identityUaServiceFactory = ({
|
|||||||
const plan = await licenseService.getPlan(identityMembershipOrg.orgId);
|
const plan = await licenseService.getPlan(identityMembershipOrg.orgId);
|
||||||
const reformattedClientSecretTrustedIps = clientSecretTrustedIps.map(
|
const reformattedClientSecretTrustedIps = clientSecretTrustedIps.map(
|
||||||
(clientSecretTrustedIp) => {
|
(clientSecretTrustedIp) => {
|
||||||
if (!plan.ipAllowlisting && clientSecretTrustedIp.ipAddress !== "0.0.0.0/0")
|
if (
|
||||||
|
!plan.ipAllowlisting &&
|
||||||
|
clientSecretTrustedIp.ipAddress !== "0.0.0.0/0" &&
|
||||||
|
clientSecretTrustedIp.ipAddress !== "::/0"
|
||||||
|
)
|
||||||
throw new BadRequestError({
|
throw new BadRequestError({
|
||||||
message:
|
message:
|
||||||
"Failed to add IP access range to service token due to plan restriction. Upgrade plan to add IP access range."
|
"Failed to add IP access range to service token due to plan restriction. Upgrade plan to add IP access range."
|
||||||
@@ -189,7 +193,11 @@ export const identityUaServiceFactory = ({
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
const reformattedAccessTokenTrustedIps = accessTokenTrustedIps.map((accessTokenTrustedIp) => {
|
const reformattedAccessTokenTrustedIps = accessTokenTrustedIps.map((accessTokenTrustedIp) => {
|
||||||
if (!plan.ipAllowlisting && accessTokenTrustedIp.ipAddress !== "0.0.0.0/0")
|
if (
|
||||||
|
!plan.ipAllowlisting &&
|
||||||
|
accessTokenTrustedIp.ipAddress !== "0.0.0.0/0" &&
|
||||||
|
accessTokenTrustedIp.ipAddress !== "::/0"
|
||||||
|
)
|
||||||
throw new BadRequestError({
|
throw new BadRequestError({
|
||||||
message:
|
message:
|
||||||
"Failed to add IP access range to service token due to plan restriction. Upgrade plan to add IP access range."
|
"Failed to add IP access range to service token due to plan restriction. Upgrade plan to add IP access range."
|
||||||
@@ -266,7 +274,11 @@ export const identityUaServiceFactory = ({
|
|||||||
const plan = await licenseService.getPlan(identityMembershipOrg.orgId);
|
const plan = await licenseService.getPlan(identityMembershipOrg.orgId);
|
||||||
const reformattedClientSecretTrustedIps = clientSecretTrustedIps?.map(
|
const reformattedClientSecretTrustedIps = clientSecretTrustedIps?.map(
|
||||||
(clientSecretTrustedIp) => {
|
(clientSecretTrustedIp) => {
|
||||||
if (!plan.ipAllowlisting && clientSecretTrustedIp.ipAddress !== "0.0.0.0/0")
|
if (
|
||||||
|
!plan.ipAllowlisting &&
|
||||||
|
clientSecretTrustedIp.ipAddress !== "0.0.0.0/0" &&
|
||||||
|
clientSecretTrustedIp.ipAddress !== "::/0"
|
||||||
|
)
|
||||||
throw new BadRequestError({
|
throw new BadRequestError({
|
||||||
message:
|
message:
|
||||||
"Failed to add IP access range to service token due to plan restriction. Upgrade plan to add IP access range."
|
"Failed to add IP access range to service token due to plan restriction. Upgrade plan to add IP access range."
|
||||||
@@ -279,7 +291,11 @@ export const identityUaServiceFactory = ({
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
const reformattedAccessTokenTrustedIps = accessTokenTrustedIps?.map((accessTokenTrustedIp) => {
|
const reformattedAccessTokenTrustedIps = accessTokenTrustedIps?.map((accessTokenTrustedIp) => {
|
||||||
if (!plan.ipAllowlisting && accessTokenTrustedIp.ipAddress !== "0.0.0.0/0")
|
if (
|
||||||
|
!plan.ipAllowlisting &&
|
||||||
|
accessTokenTrustedIp.ipAddress !== "0.0.0.0/0" &&
|
||||||
|
accessTokenTrustedIp.ipAddress !== "::/0"
|
||||||
|
)
|
||||||
throw new BadRequestError({
|
throw new BadRequestError({
|
||||||
message:
|
message:
|
||||||
"Failed to add IP access range to service token due to plan restriction. Upgrade plan to add IP access range."
|
"Failed to add IP access range to service token due to plan restriction. Upgrade plan to add IP access range."
|
||||||
|
|||||||
@@ -234,13 +234,7 @@ export const integrationAuthServiceFactory = ({
|
|||||||
updateDoc.accessIdCiphertext = accessEncToken.ciphertext;
|
updateDoc.accessIdCiphertext = accessEncToken.ciphertext;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return integrationAuthDal.transaction(async (tx) => {
|
return integrationAuthDal.create(updateDoc);
|
||||||
const doc = await integrationAuthDal.findOne({ projectId, integration }, tx);
|
|
||||||
if (!doc) {
|
|
||||||
return integrationAuthDal.create(updateDoc, tx);
|
|
||||||
}
|
|
||||||
return integrationAuthDal.updateById(doc.id, updateDoc, tx);
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// helper function
|
// helper function
|
||||||
|
|||||||
@@ -16,12 +16,14 @@ import {
|
|||||||
TDeleteIntegrationDTO,
|
TDeleteIntegrationDTO,
|
||||||
TUpdateIntegrationDTO
|
TUpdateIntegrationDTO
|
||||||
} from "./integration-types";
|
} from "./integration-types";
|
||||||
|
import { TSecretQueueFactory } from "../secret/secret-queue";
|
||||||
|
|
||||||
type TIntegrationServiceFactoryDep = {
|
type TIntegrationServiceFactoryDep = {
|
||||||
integrationDal: TIntegrationDalFactory;
|
integrationDal: TIntegrationDalFactory;
|
||||||
integrationAuthDal: TIntegrationAuthDalFactory;
|
integrationAuthDal: TIntegrationAuthDalFactory;
|
||||||
folderDal: Pick<TSecretFolderDalFactory, "findBySecretPath">;
|
folderDal: Pick<TSecretFolderDalFactory, "findBySecretPath">;
|
||||||
permissionService: Pick<TPermissionServiceFactory, "getProjectPermission">;
|
permissionService: Pick<TPermissionServiceFactory, "getProjectPermission">;
|
||||||
|
secretQueueService: Pick<TSecretQueueFactory, "syncIntegrations">;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TIntegrationServiceFactory = ReturnType<typeof integrationServiceFactory>;
|
export type TIntegrationServiceFactory = ReturnType<typeof integrationServiceFactory>;
|
||||||
@@ -30,7 +32,8 @@ export const integrationServiceFactory = ({
|
|||||||
integrationDal,
|
integrationDal,
|
||||||
integrationAuthDal,
|
integrationAuthDal,
|
||||||
folderDal,
|
folderDal,
|
||||||
permissionService
|
permissionService,
|
||||||
|
secretQueueService
|
||||||
}: TIntegrationServiceFactoryDep) => {
|
}: TIntegrationServiceFactoryDep) => {
|
||||||
const createIntegration = async ({
|
const createIntegration = async ({
|
||||||
app,
|
app,
|
||||||
@@ -90,7 +93,11 @@ export const integrationServiceFactory = ({
|
|||||||
integration: integrationAuth.integration
|
integration: integrationAuth.integration
|
||||||
});
|
});
|
||||||
|
|
||||||
|
await secretQueueService.syncIntegrations({
|
||||||
|
environment: sourceEnvironment,
|
||||||
|
secretPath,
|
||||||
|
projectId: integrationAuth.projectId
|
||||||
|
});
|
||||||
return { integration, integrationAuth };
|
return { integration, integrationAuth };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -48,20 +48,8 @@ export const secretQueueFactory = ({
|
|||||||
webhookDal,
|
webhookDal,
|
||||||
projectEnvDal
|
projectEnvDal
|
||||||
}: TSecretQueueFactoryDep) => {
|
}: TSecretQueueFactoryDep) => {
|
||||||
const syncSecrets = async (dto: TGetSecrets) => {
|
const syncIntegrations = async (dto: TGetSecrets) => {
|
||||||
queueService.queue(QueueName.SecretWebhook, QueueJobs.SecWebhook, dto, {
|
await queueService.queue(QueueName.IntegrationSync, QueueJobs.IntegrationSync, dto, {
|
||||||
jobId: `secret-webhook-${dto.environment}-${dto.projectId}-${dto.secretPath}`,
|
|
||||||
removeOnFail: { count: 5 },
|
|
||||||
removeOnComplete: true,
|
|
||||||
delay: 1000,
|
|
||||||
attempts: 5,
|
|
||||||
backoff: {
|
|
||||||
type: "exponential",
|
|
||||||
delay: 3000
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
queueService.queue(QueueName.IntegrationSync, QueueJobs.IntegrationSync, dto, {
|
|
||||||
attempts: 5,
|
attempts: 5,
|
||||||
delay: 1000,
|
delay: 1000,
|
||||||
backoff: {
|
backoff: {
|
||||||
@@ -75,6 +63,21 @@ export const secretQueueFactory = ({
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const syncSecrets = async (dto: TGetSecrets) => {
|
||||||
|
await queueService.queue(QueueName.SecretWebhook, QueueJobs.SecWebhook, dto, {
|
||||||
|
jobId: `secret-webhook-${dto.environment}-${dto.projectId}-${dto.secretPath}`,
|
||||||
|
removeOnFail: { count: 5 },
|
||||||
|
removeOnComplete: true,
|
||||||
|
delay: 1000,
|
||||||
|
attempts: 5,
|
||||||
|
backoff: {
|
||||||
|
type: "exponential",
|
||||||
|
delay: 3000
|
||||||
|
}
|
||||||
|
});
|
||||||
|
await syncIntegrations(dto);
|
||||||
|
};
|
||||||
|
|
||||||
const getIntegrationSecrets = async (dto: TGetSecrets & { folderId: string }, key: string) => {
|
const getIntegrationSecrets = async (dto: TGetSecrets & { folderId: string }, key: string) => {
|
||||||
const secrets = await secretDal.findByFolderId(dto.folderId);
|
const secrets = await secretDal.findByFolderId(dto.folderId);
|
||||||
if (!secrets.length) return {};
|
if (!secrets.length) return {};
|
||||||
@@ -226,5 +229,5 @@ export const secretQueueFactory = ({
|
|||||||
await fnTriggerWebhook({ ...job.data, projectEnvDal, webhookDal });
|
await fnTriggerWebhook({ ...job.data, projectEnvDal, webhookDal });
|
||||||
});
|
});
|
||||||
|
|
||||||
return { syncSecrets };
|
return { syncSecrets, syncIntegrations };
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user