mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-09-22 13:39:35 +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) => {
|
||||
try {
|
||||
const [res] = await (tx || db)(tableName).insert(data).returning("*");
|
||||
const [res] = await (tx || db)(tableName)
|
||||
.insert(data as any)
|
||||
.returning("*");
|
||||
return res;
|
||||
} catch (error) {
|
||||
throw new DatabaseError({ error, name: "Create" });
|
||||
|
||||
@@ -392,7 +392,8 @@ export const registerRoutes = async (
|
||||
permissionService,
|
||||
folderDal,
|
||||
integrationDal,
|
||||
integrationAuthDal
|
||||
integrationAuthDal,
|
||||
secretQueueService
|
||||
});
|
||||
const serviceTokenService = serviceTokenServiceFactory({
|
||||
projectEnvDal,
|
||||
|
||||
@@ -81,14 +81,14 @@ export const registerIdentityUaRouter = async (server: FastifyZodProvider) => {
|
||||
})
|
||||
.array()
|
||||
.min(1)
|
||||
.default([{ ipAddress: "0.0.0.0/0" }]),
|
||||
.default([{ ipAddress: "0.0.0.0/0" }, { ipAddress: "::/0" }]),
|
||||
accessTokenTrustedIps: z
|
||||
.object({
|
||||
ipAddress: z.string().trim()
|
||||
})
|
||||
.array()
|
||||
.min(1)
|
||||
.default([{ ipAddress: "0.0.0.0/0" }]),
|
||||
.default([{ ipAddress: "0.0.0.0/0" }, { ipAddress: "::/0" }]),
|
||||
accessTokenTTL: z
|
||||
.number()
|
||||
.int()
|
||||
|
||||
@@ -69,7 +69,7 @@ export const tokenServiceFactory = ({ tokenDal, userDal }: TAuthTokenServiceFact
|
||||
const newToken = await tokenDal.create(
|
||||
{
|
||||
tokenHash,
|
||||
expiresAt: tkCfg.expiresAt.toUTCString(),
|
||||
expiresAt: tkCfg.expiresAt,
|
||||
type,
|
||||
userId,
|
||||
orgId,
|
||||
|
||||
@@ -14,7 +14,7 @@ import { TPermissionServiceFactory } from "@app/ee/services/permission/permissio
|
||||
import { isAtLeastAsPrivileged } from "@app/lib/casl";
|
||||
import { getConfig } from "@app/lib/config/env";
|
||||
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 { TIdentityDalFactory } from "../identity/identity-dal";
|
||||
@@ -176,7 +176,11 @@ export const identityUaServiceFactory = ({
|
||||
const plan = await licenseService.getPlan(identityMembershipOrg.orgId);
|
||||
const reformattedClientSecretTrustedIps = clientSecretTrustedIps.map(
|
||||
(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({
|
||||
message:
|
||||
"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) => {
|
||||
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({
|
||||
message:
|
||||
"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 reformattedClientSecretTrustedIps = clientSecretTrustedIps?.map(
|
||||
(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({
|
||||
message:
|
||||
"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) => {
|
||||
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({
|
||||
message:
|
||||
"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;
|
||||
}
|
||||
}
|
||||
return integrationAuthDal.transaction(async (tx) => {
|
||||
const doc = await integrationAuthDal.findOne({ projectId, integration }, tx);
|
||||
if (!doc) {
|
||||
return integrationAuthDal.create(updateDoc, tx);
|
||||
}
|
||||
return integrationAuthDal.updateById(doc.id, updateDoc, tx);
|
||||
});
|
||||
return integrationAuthDal.create(updateDoc);
|
||||
};
|
||||
|
||||
// helper function
|
||||
|
||||
@@ -16,12 +16,14 @@ import {
|
||||
TDeleteIntegrationDTO,
|
||||
TUpdateIntegrationDTO
|
||||
} from "./integration-types";
|
||||
import { TSecretQueueFactory } from "../secret/secret-queue";
|
||||
|
||||
type TIntegrationServiceFactoryDep = {
|
||||
integrationDal: TIntegrationDalFactory;
|
||||
integrationAuthDal: TIntegrationAuthDalFactory;
|
||||
folderDal: Pick<TSecretFolderDalFactory, "findBySecretPath">;
|
||||
permissionService: Pick<TPermissionServiceFactory, "getProjectPermission">;
|
||||
secretQueueService: Pick<TSecretQueueFactory, "syncIntegrations">;
|
||||
};
|
||||
|
||||
export type TIntegrationServiceFactory = ReturnType<typeof integrationServiceFactory>;
|
||||
@@ -30,7 +32,8 @@ export const integrationServiceFactory = ({
|
||||
integrationDal,
|
||||
integrationAuthDal,
|
||||
folderDal,
|
||||
permissionService
|
||||
permissionService,
|
||||
secretQueueService
|
||||
}: TIntegrationServiceFactoryDep) => {
|
||||
const createIntegration = async ({
|
||||
app,
|
||||
@@ -90,7 +93,11 @@ export const integrationServiceFactory = ({
|
||||
integration: integrationAuth.integration
|
||||
});
|
||||
|
||||
|
||||
await secretQueueService.syncIntegrations({
|
||||
environment: sourceEnvironment,
|
||||
secretPath,
|
||||
projectId: integrationAuth.projectId
|
||||
});
|
||||
return { integration, integrationAuth };
|
||||
};
|
||||
|
||||
|
||||
@@ -48,20 +48,8 @@ export const secretQueueFactory = ({
|
||||
webhookDal,
|
||||
projectEnvDal
|
||||
}: TSecretQueueFactoryDep) => {
|
||||
const syncSecrets = async (dto: TGetSecrets) => {
|
||||
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
|
||||
}
|
||||
});
|
||||
|
||||
queueService.queue(QueueName.IntegrationSync, QueueJobs.IntegrationSync, dto, {
|
||||
const syncIntegrations = async (dto: TGetSecrets) => {
|
||||
await queueService.queue(QueueName.IntegrationSync, QueueJobs.IntegrationSync, dto, {
|
||||
attempts: 5,
|
||||
delay: 1000,
|
||||
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 secrets = await secretDal.findByFolderId(dto.folderId);
|
||||
if (!secrets.length) return {};
|
||||
@@ -226,5 +229,5 @@ export const secretQueueFactory = ({
|
||||
await fnTriggerWebhook({ ...job.data, projectEnvDal, webhookDal });
|
||||
});
|
||||
|
||||
return { syncSecrets };
|
||||
return { syncSecrets, syncIntegrations };
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user