mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-09-22 13:39:35 +00:00
Merge pull request #1343 from Infisical/daniel/pg-endpoint-fixes
(Postgres Fix): Secret endpoints return data
This commit is contained in:
@@ -13,7 +13,7 @@ module.exports = {
|
||||
tsconfigRootDir: __dirname
|
||||
},
|
||||
rules: {
|
||||
// "@typescript-eslint/no-empty-function": "off",
|
||||
"@typescript-eslint/no-empty-function": "off",
|
||||
"consistent-return": "off", // my style
|
||||
"import/order": "off", // for simple-import-order
|
||||
"import/prefer-default-export": "off", // why
|
||||
|
||||
@@ -8,7 +8,7 @@ import { z } from "zod";
|
||||
import { TImmutableDBKeys } from "./models";
|
||||
|
||||
export const IdentityAccessTokensSchema = z.object({
|
||||
id: z.string().uuid(),
|
||||
id: z.string(),
|
||||
accessTokenTTL: z.coerce.number().default(2592000),
|
||||
accessTokenMaxTTL: z.coerce.number().default(2592000),
|
||||
accessTokenNumUses: z.coerce.number().default(0),
|
||||
|
||||
@@ -13,7 +13,7 @@ export const OrganizationsSchema = z.object({
|
||||
customerId: z.string().nullable().optional(),
|
||||
slug: z.string(),
|
||||
createdAt: z.date(),
|
||||
updatedAt: z.date()
|
||||
updatedAt: z.date(),
|
||||
});
|
||||
|
||||
export type TOrganizations = z.infer<typeof OrganizationsSchema>;
|
||||
|
||||
@@ -10,7 +10,7 @@ import { TImmutableDBKeys } from "./models";
|
||||
export const SecretApprovalRequestsSecretsSchema = z.object({
|
||||
id: z.string().uuid(),
|
||||
version: z.number().default(1).nullable().optional(),
|
||||
secretBlindIndex: z.string(),
|
||||
secretBlindIndex: z.string().nullable().optional(),
|
||||
secretKeyCiphertext: z.string(),
|
||||
secretKeyIV: z.string(),
|
||||
secretKeyTag: z.string(),
|
||||
|
||||
@@ -12,9 +12,9 @@ export const UserEncryptionKeysSchema = z.object({
|
||||
clientPublicKey: z.string().nullable().optional(),
|
||||
serverPrivateKey: z.string().nullable().optional(),
|
||||
encryptionVersion: z.number().default(2).nullable().optional(),
|
||||
protectedKey: z.string().nullable(),
|
||||
protectedKeyIV: z.string().nullable(),
|
||||
protectedKeyTag: z.string().nullable(),
|
||||
protectedKey: z.string().nullable().optional(),
|
||||
protectedKeyIV: z.string().nullable().optional(),
|
||||
protectedKeyTag: z.string().nullable().optional(),
|
||||
publicKey: z.string(),
|
||||
encryptedPrivateKey: z.string(),
|
||||
iv: z.string(),
|
||||
|
||||
@@ -269,7 +269,14 @@ export const secretApprovalRequestServiceFactory = ({
|
||||
const { secsGroupedByBlindIndex: conflictGroupByBlindIndex } =
|
||||
await secretService.fnSecretBlindIndexCheckV2({
|
||||
folderId,
|
||||
inputSecrets: secretCreationCommits.map(({ secretBlindIndex }) => ({ secretBlindIndex }))
|
||||
inputSecrets: secretCreationCommits.map(({ secretBlindIndex }) => {
|
||||
if (!secretBlindIndex) {
|
||||
throw new BadRequestError({
|
||||
message: "Missing secret blind index"
|
||||
});
|
||||
}
|
||||
return { secretBlindIndex };
|
||||
})
|
||||
});
|
||||
secretCreationCommits
|
||||
.filter(({ secretBlindIndex }) => conflictGroupByBlindIndex[secretBlindIndex || ""])
|
||||
@@ -291,7 +298,14 @@ export const secretApprovalRequestServiceFactory = ({
|
||||
({ secretBlindIndex, secret }) =>
|
||||
secret && secret.secretBlindIndex !== secretBlindIndex
|
||||
)
|
||||
.map(({ secretBlindIndex }) => ({ secretBlindIndex }))
|
||||
.map(({ secretBlindIndex }) => {
|
||||
if (!secretBlindIndex) {
|
||||
throw new BadRequestError({
|
||||
message: "Missing secret blind index"
|
||||
});
|
||||
}
|
||||
return { secretBlindIndex };
|
||||
})
|
||||
});
|
||||
secretUpdationCommits
|
||||
.filter(
|
||||
@@ -381,10 +395,14 @@ export const secretApprovalRequestServiceFactory = ({
|
||||
folderId,
|
||||
tx,
|
||||
actorId: "",
|
||||
inputSecrets: secretDeletionCommits.map(({ secretBlindIndex }) => ({
|
||||
secretBlindIndex,
|
||||
type: SecretType.Shared
|
||||
}))
|
||||
inputSecrets: secretDeletionCommits.map(({ secretBlindIndex }) => {
|
||||
if (!secretBlindIndex) {
|
||||
throw new BadRequestError({
|
||||
message: "Missing secret blind index"
|
||||
});
|
||||
}
|
||||
return { secretBlindIndex, type: SecretType.Shared };
|
||||
})
|
||||
})
|
||||
: [];
|
||||
const updatedSecretApproval = await secretApprovalRequestDAL.updateById(
|
||||
@@ -638,7 +656,13 @@ export const secretApprovalRequestServiceFactory = ({
|
||||
),
|
||||
tx
|
||||
);
|
||||
const commitsGroupByBlindIndex = groupBy(approvalCommits, (i) => i.secretBlindIndex);
|
||||
|
||||
const commitsGroupByBlindIndex = groupBy(approvalCommits, (i) => {
|
||||
if (!i.secretBlindIndex) {
|
||||
throw new BadRequestError({ message: "Missing secret blind index" });
|
||||
}
|
||||
return i.secretBlindIndex;
|
||||
});
|
||||
if (tagIds.length) {
|
||||
await secretApprovalRequestSecretDAL.insertApprovalSecretTags(
|
||||
Object.keys(commitTagIds).flatMap((blindIndex) =>
|
||||
|
||||
@@ -92,7 +92,10 @@ import { serviceTokenDALFactory } from "@app/services/service-token/service-toke
|
||||
import { serviceTokenServiceFactory } from "@app/services/service-token/service-token-service";
|
||||
import { TSmtpService } from "@app/services/smtp/smtp-service";
|
||||
import { superAdminDALFactory } from "@app/services/super-admin/super-admin-dal";
|
||||
import { getServerCfg, superAdminServiceFactory } from "@app/services/super-admin/super-admin-service";
|
||||
import {
|
||||
getServerCfg,
|
||||
superAdminServiceFactory
|
||||
} from "@app/services/super-admin/super-admin-service";
|
||||
import { telemetryServiceFactory } from "@app/services/telemetry/telemetry-service";
|
||||
import { userDALFactory } from "@app/services/user/user-dal";
|
||||
import { userServiceFactory } from "@app/services/user/user-service";
|
||||
@@ -420,6 +423,7 @@ export const registerRoutes = async (
|
||||
const serviceTokenService = serviceTokenServiceFactory({
|
||||
projectEnvDAL,
|
||||
serviceTokenDAL,
|
||||
userDAL,
|
||||
permissionService
|
||||
});
|
||||
|
||||
@@ -516,14 +520,14 @@ export const registerRoutes = async (
|
||||
},
|
||||
handler: () => {
|
||||
const cfg = getConfig();
|
||||
const serverCfg = getServerCfg()
|
||||
const serverCfg = getServerCfg();
|
||||
return {
|
||||
date: new Date(),
|
||||
message: "Ok" as const,
|
||||
emailConfigured: cfg.isSmtpConfigured,
|
||||
inviteOnlySignup: Boolean(serverCfg.allowSignUp),
|
||||
redisConfigured: cfg.isRedisConfigured,
|
||||
secretScanningConfigured: cfg.isSecretScanningConfigured,
|
||||
secretScanningConfigured: cfg.isSecretScanningConfigured
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { z } from "zod";
|
||||
|
||||
import { IntegrationAuthsSchema, SecretApprovalPoliciesSchema } from "@app/db/schemas";
|
||||
import { IntegrationAuthsSchema, SecretApprovalPoliciesSchema, UsersSchema } from "@app/db/schemas";
|
||||
|
||||
// sometimes the return data must be santizied to avoid leaking important values
|
||||
// always prefer pick over omit in zod
|
||||
@@ -28,6 +28,18 @@ export const sapPubSchema = SecretApprovalPoliciesSchema.merge(
|
||||
})
|
||||
);
|
||||
|
||||
export const sanitizedServiceTokenUserSchema = UsersSchema.pick({
|
||||
authMethods: true,
|
||||
id: true,
|
||||
createdAt: true,
|
||||
updatedAt: true,
|
||||
devices: true,
|
||||
email: true,
|
||||
firstName: true,
|
||||
lastName: true,
|
||||
mfaMethods: true
|
||||
});
|
||||
|
||||
export const secretRawSchema = z.object({
|
||||
id: z.string(),
|
||||
_id: z.string(),
|
||||
|
||||
@@ -86,7 +86,13 @@ export const registerMfaRouter = async (server: FastifyZodProvider) => {
|
||||
secure: appCfg.HTTPS_ENABLED
|
||||
});
|
||||
|
||||
return { token: token.access, ...user };
|
||||
return {
|
||||
...user,
|
||||
token: token.access,
|
||||
protectedKey: user.protectedKey || null,
|
||||
protectedKeyIV: user.protectedKeyIV || null,
|
||||
protectedKeyTag: user.protectedKeyTag || null
|
||||
};
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
@@ -6,6 +6,8 @@ import { removeTrailingSlash } from "@app/lib/fn";
|
||||
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
|
||||
import { AuthMode } from "@app/services/auth/auth-type";
|
||||
|
||||
import { sanitizedServiceTokenUserSchema } from "../sanitizedSchemas";
|
||||
|
||||
export const sanitizedServiceTokenSchema = ServiceTokensSchema.omit({
|
||||
secretHash: true,
|
||||
encryptedKey: true,
|
||||
@@ -20,15 +22,22 @@ export const registerServiceTokenRouter = async (server: FastifyZodProvider) =>
|
||||
onRequest: verifyAuth([AuthMode.SERVICE_TOKEN]),
|
||||
schema: {
|
||||
response: {
|
||||
200: ServiceTokensSchema.merge(z.object({ workspace: z.string() }))
|
||||
200: ServiceTokensSchema.merge(
|
||||
z.object({
|
||||
workspace: z.string(),
|
||||
user: sanitizedServiceTokenUserSchema
|
||||
})
|
||||
)
|
||||
}
|
||||
},
|
||||
handler: async (req) => {
|
||||
const serviceTokenData = await server.services.serviceToken.getServiceToken({
|
||||
const { serviceToken, user } = await server.services.serviceToken.getServiceToken({
|
||||
actorId: req.permission.id,
|
||||
actor: req.permission.type
|
||||
});
|
||||
return { ...serviceTokenData, workspace: serviceTokenData.projectId };
|
||||
|
||||
// We return the user here because older versions of the deprecated Python SDK depend on it to properly parse the API response.
|
||||
return { ...serviceToken, workspace: serviceToken.projectId, user };
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -96,9 +96,9 @@ export const registerLoginRouter = async (server: FastifyZodProvider) => {
|
||||
encryptedPrivateKey: data.user.encryptedPrivateKey,
|
||||
iv: data.user.iv,
|
||||
tag: data.user.tag,
|
||||
protectedKey: data.user.protectedKey,
|
||||
protectedKeyIV: data.user.protectedKeyIV,
|
||||
protectedKeyTag: data.user.protectedKeyTag
|
||||
protectedKey: data.user.protectedKey || null,
|
||||
protectedKeyIV: data.user.protectedKeyIV || null,
|
||||
protectedKeyTag: data.user.protectedKeyTag || null
|
||||
} as const;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -442,6 +442,8 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
||||
secrets: SecretsSchema.omit({ secretBlindIndex: true })
|
||||
.merge(
|
||||
z.object({
|
||||
workspace: z.string(),
|
||||
environment: z.string(),
|
||||
tags: SecretTagsSchema.pick({
|
||||
id: true,
|
||||
slug: true,
|
||||
@@ -529,7 +531,12 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
||||
}),
|
||||
response: {
|
||||
200: z.object({
|
||||
secret: SecretsSchema.omit({ secretBlindIndex: true })
|
||||
secret: SecretsSchema.omit({ secretBlindIndex: true }).merge(
|
||||
z.object({
|
||||
workspace: z.string(),
|
||||
environment: z.string()
|
||||
})
|
||||
)
|
||||
})
|
||||
}
|
||||
},
|
||||
@@ -610,7 +617,12 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
||||
response: {
|
||||
200: z.union([
|
||||
z.object({
|
||||
secret: SecretsSchema.omit({ secretBlindIndex: true })
|
||||
secret: SecretsSchema.omit({ secretBlindIndex: true }).merge(
|
||||
z.object({
|
||||
workspace: z.string(),
|
||||
environment: z.string()
|
||||
})
|
||||
)
|
||||
}),
|
||||
z
|
||||
.object({ approval: SecretApprovalRequestsSchema })
|
||||
@@ -780,7 +792,12 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
||||
response: {
|
||||
200: z.union([
|
||||
z.object({
|
||||
secret: SecretsSchema.omit({ secretBlindIndex: true })
|
||||
secret: SecretsSchema.omit({ secretBlindIndex: true }).merge(
|
||||
z.object({
|
||||
workspace: z.string(),
|
||||
environment: z.string()
|
||||
})
|
||||
)
|
||||
}),
|
||||
z
|
||||
.object({ approval: SecretApprovalRequestsSchema })
|
||||
@@ -944,7 +961,12 @@ export const registerSecretRouter = async (server: FastifyZodProvider) => {
|
||||
response: {
|
||||
200: z.union([
|
||||
z.object({
|
||||
secret: SecretsSchema.omit({ secretBlindIndex: true })
|
||||
secret: SecretsSchema.omit({ secretBlindIndex: true }).merge(
|
||||
z.object({
|
||||
workspace: z.string(),
|
||||
environment: z.string()
|
||||
})
|
||||
)
|
||||
}),
|
||||
z
|
||||
.object({ approval: SecretApprovalRequestsSchema })
|
||||
|
||||
@@ -13,6 +13,7 @@ import { BadRequestError, UnauthorizedError } from "@app/lib/errors";
|
||||
|
||||
import { ActorType } from "../auth/auth-type";
|
||||
import { TProjectEnvDALFactory } from "../project-env/project-env-dal";
|
||||
import { TUserDALFactory } from "../user/user-dal";
|
||||
import { TServiceTokenDALFactory } from "./service-token-dal";
|
||||
import {
|
||||
TCreateServiceTokenDTO,
|
||||
@@ -23,6 +24,7 @@ import {
|
||||
|
||||
type TServiceTokenServiceFactoryDep = {
|
||||
serviceTokenDAL: TServiceTokenDALFactory;
|
||||
userDAL: TUserDALFactory;
|
||||
permissionService: Pick<TPermissionServiceFactory, "getProjectPermission">;
|
||||
projectEnvDAL: Pick<TProjectEnvDALFactory, "findBySlugs">;
|
||||
};
|
||||
@@ -31,6 +33,7 @@ export type TServiceTokenServiceFactory = ReturnType<typeof serviceTokenServiceF
|
||||
|
||||
export const serviceTokenServiceFactory = ({
|
||||
serviceTokenDAL,
|
||||
userDAL,
|
||||
permissionService,
|
||||
projectEnvDAL
|
||||
}: TServiceTokenServiceFactoryDep) => {
|
||||
@@ -51,14 +54,14 @@ export const serviceTokenServiceFactory = ({
|
||||
ProjectPermissionActions.Create,
|
||||
ProjectPermissionSub.ServiceTokens
|
||||
);
|
||||
|
||||
|
||||
scopes.forEach(({ environment, secretPath }) => {
|
||||
ForbiddenError.from(permission).throwUnlessCan(
|
||||
ProjectPermissionActions.Create,
|
||||
subject(ProjectPermissionSub.Secrets, { environment, secretPath })
|
||||
);
|
||||
})
|
||||
|
||||
});
|
||||
|
||||
const appCfg = getConfig();
|
||||
|
||||
// validates env
|
||||
@@ -119,7 +122,10 @@ export const serviceTokenServiceFactory = ({
|
||||
const serviceToken = await serviceTokenDAL.findById(actorId);
|
||||
if (!serviceToken) throw new BadRequestError({ message: "Token not found" });
|
||||
|
||||
return serviceToken;
|
||||
const serviceTokenUser = await userDAL.findById(serviceToken.createdBy);
|
||||
if (!serviceTokenUser) throw new BadRequestError({ message: "Service token user not found" });
|
||||
|
||||
return { serviceToken, user: serviceTokenUser };
|
||||
};
|
||||
|
||||
const getProjectServiceTokens = async ({
|
||||
|
||||
Reference in New Issue
Block a user