mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-11 11:29:21 +00:00
requested changes & edge cases
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import { ForbiddenError } from "@casl/ability";
|
||||
import { z } from "zod";
|
||||
|
||||
import { SecretFoldersSchema, SecretImportsSchema } from "@app/db/schemas";
|
||||
import { SecretFoldersSchema, SecretImportsSchema, UsersSchema } from "@app/db/schemas";
|
||||
import { EventType, UserAgentType } from "@app/ee/services/audit-log/audit-log-types";
|
||||
import { ProjectPermissionSecretActions } from "@app/ee/services/permission/project-permission";
|
||||
import { SecretRotationV2Schema } from "@app/ee/services/secret-rotation-v2/secret-rotation-v2-union-schema";
|
||||
@@ -594,6 +594,12 @@ export const registerDashboardRouter = async (server: FastifyZodProvider) => {
|
||||
.optional(),
|
||||
secrets: secretRawSchema
|
||||
.extend({
|
||||
secretReminderRecipients: z
|
||||
.object({
|
||||
user: UsersSchema.pick({ id: true, email: true, username: true }),
|
||||
id: z.string()
|
||||
})
|
||||
.array(),
|
||||
secretValueHidden: z.boolean(),
|
||||
secretPath: z.string().optional(),
|
||||
secretMetadata: ResourceMetadataSchema.optional(),
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
export type TSecretReminderRecipient = {
|
||||
user: {
|
||||
id: string;
|
||||
username: string;
|
||||
email?: string | null;
|
||||
};
|
||||
id: string;
|
||||
};
|
||||
@@ -95,7 +95,17 @@ export const secretV2BridgeDALFactory = ({ db, keyStore }: TSecretV2DalArg) => {
|
||||
`${TableName.SecretV2}.id`,
|
||||
`${TableName.SecretRotationV2SecretMapping}.secretId`
|
||||
)
|
||||
.leftJoin(
|
||||
TableName.SecretReminderRecipients,
|
||||
`${TableName.SecretV2}.id`,
|
||||
`${TableName.SecretReminderRecipients}.secretId`
|
||||
)
|
||||
.leftJoin(TableName.Users, `${TableName.SecretReminderRecipients}.userId`, `${TableName.Users}.id`)
|
||||
.select(selectAllTableCols(TableName.SecretV2))
|
||||
.select(db.ref("id").withSchema(TableName.SecretReminderRecipients).as("reminderRecipientId"))
|
||||
.select(db.ref("username").withSchema(TableName.Users).as("reminderRecipientUsername"))
|
||||
.select(db.ref("email").withSchema(TableName.Users).as("reminderRecipientEmail"))
|
||||
.select(db.ref("id").withSchema(TableName.Users).as("reminderRecipientUserId"))
|
||||
.select(db.ref("id").withSchema(TableName.SecretTag).as("tagId"))
|
||||
.select(db.ref("color").withSchema(TableName.SecretTag).as("tagColor"))
|
||||
.select(db.ref("slug").withSchema(TableName.SecretTag).as("tagSlug"))
|
||||
@@ -119,6 +129,23 @@ export const secretV2BridgeDALFactory = ({ db, keyStore }: TSecretV2DalArg) => {
|
||||
slug,
|
||||
name: slug
|
||||
})
|
||||
},
|
||||
{
|
||||
key: "reminderRecipientId",
|
||||
label: "secretReminderRecipients" as const,
|
||||
mapper: ({
|
||||
reminderRecipientId,
|
||||
reminderRecipientUsername,
|
||||
reminderRecipientEmail,
|
||||
reminderRecipientUserId
|
||||
}) => ({
|
||||
user: {
|
||||
id: reminderRecipientUserId,
|
||||
username: reminderRecipientUsername,
|
||||
email: reminderRecipientEmail
|
||||
},
|
||||
id: reminderRecipientId
|
||||
})
|
||||
}
|
||||
]
|
||||
});
|
||||
@@ -607,6 +634,12 @@ export const secretV2BridgeDALFactory = ({ db, keyStore }: TSecretV2DalArg) => {
|
||||
`${TableName.SecretV2JnTag}.${TableName.SecretTag}Id`,
|
||||
`${TableName.SecretTag}.id`
|
||||
)
|
||||
.leftJoin(
|
||||
TableName.SecretReminderRecipients,
|
||||
`${TableName.SecretV2}.id`,
|
||||
`${TableName.SecretReminderRecipients}.secretId`
|
||||
)
|
||||
.leftJoin(TableName.Users, `${TableName.SecretReminderRecipients}.userId`, `${TableName.Users}.id`)
|
||||
.leftJoin(TableName.ResourceMetadata, `${TableName.SecretV2}.id`, `${TableName.ResourceMetadata}.secretId`)
|
||||
.leftJoin(
|
||||
TableName.SecretRotationV2SecretMapping,
|
||||
@@ -635,6 +668,10 @@ export const secretV2BridgeDALFactory = ({ db, keyStore }: TSecretV2DalArg) => {
|
||||
}) as rank`
|
||||
)
|
||||
)
|
||||
.select(db.ref("id").withSchema(TableName.SecretReminderRecipients).as("reminderRecipientId"))
|
||||
.select(db.ref("username").withSchema(TableName.Users).as("reminderRecipientUsername"))
|
||||
.select(db.ref("email").withSchema(TableName.Users).as("reminderRecipientEmail"))
|
||||
.select(db.ref("id").withSchema(TableName.Users).as("reminderRecipientUserId"))
|
||||
.select(db.ref("id").withSchema(TableName.SecretTag).as("tagId"))
|
||||
.select(db.ref("color").withSchema(TableName.SecretTag).as("tagColor"))
|
||||
.select(db.ref("slug").withSchema(TableName.SecretTag).as("tagSlug"))
|
||||
@@ -679,6 +716,23 @@ export const secretV2BridgeDALFactory = ({ db, keyStore }: TSecretV2DalArg) => {
|
||||
isRotatedSecret: Boolean(el.rotationId)
|
||||
}),
|
||||
childrenMapper: [
|
||||
{
|
||||
key: "reminderRecipientId",
|
||||
label: "secretReminderRecipients" as const,
|
||||
mapper: ({
|
||||
reminderRecipientId,
|
||||
reminderRecipientUsername,
|
||||
reminderRecipientEmail,
|
||||
reminderRecipientUserId
|
||||
}) => ({
|
||||
user: {
|
||||
id: reminderRecipientUserId,
|
||||
username: reminderRecipientUsername,
|
||||
email: reminderRecipientEmail
|
||||
},
|
||||
id: reminderRecipientId
|
||||
})
|
||||
},
|
||||
{
|
||||
key: "tagId",
|
||||
label: "tags" as const,
|
||||
|
||||
@@ -10,6 +10,7 @@ import { TProjectEnvDALFactory } from "../project-env/project-env-dal";
|
||||
import { ResourceMetadataDTO } from "../resource-metadata/resource-metadata-schema";
|
||||
import { INFISICAL_SECRET_VALUE_HIDDEN_MASK } from "../secret/secret-fns";
|
||||
import { TSecretFolderDALFactory } from "../secret-folder/secret-folder-dal";
|
||||
import { TSecretReminderRecipient } from "../secret-reminder-recipients/secret-reminder-recipients-types";
|
||||
import { TSecretV2BridgeDALFactory } from "./secret-v2-bridge-dal";
|
||||
import { TFnSecretBulkDelete, TFnSecretBulkInsert, TFnSecretBulkUpdate } from "./secret-v2-bridge-types";
|
||||
|
||||
@@ -668,6 +669,7 @@ export const reshapeBridgeSecret = (
|
||||
secretMetadata?: ResourceMetadataDTO;
|
||||
isRotatedSecret?: boolean;
|
||||
rotationId?: string;
|
||||
secretReminderRecipients?: TSecretReminderRecipient[];
|
||||
},
|
||||
secretValueHidden: boolean
|
||||
) => ({
|
||||
@@ -699,6 +701,7 @@ export const reshapeBridgeSecret = (
|
||||
updatedAt: secret.updatedAt,
|
||||
isRotatedSecret: secret.isRotatedSecret,
|
||||
rotationId: secret.rotationId,
|
||||
secretReminderRecipients: secret.secretReminderRecipients || [],
|
||||
...(secretValueHidden
|
||||
? {
|
||||
secretValue: INFISICAL_SECRET_VALUE_HIDDEN_MASK,
|
||||
|
||||
@@ -539,7 +539,8 @@ export const secretV2BridgeServiceFactory = ({
|
||||
oldSecret: {
|
||||
id: secret.id,
|
||||
secretReminderNote: secret.reminderNote,
|
||||
secretReminderRepeatDays: secret.reminderRepeatDays
|
||||
secretReminderRepeatDays: secret.reminderRepeatDays,
|
||||
secretReminderRecipients: secret.secretReminderRecipients?.map((el) => el.user.id)
|
||||
},
|
||||
projectId
|
||||
});
|
||||
|
||||
@@ -396,6 +396,7 @@ export const decryptSecretRaw = (
|
||||
id: secret.id,
|
||||
user: secret.userId,
|
||||
tags: secret.tags?.map((el) => ({ ...el, name: el.slug })),
|
||||
secretReminderRecipients: [],
|
||||
skipMultilineEncoding: secret.skipMultilineEncoding,
|
||||
secretReminderRepeatDays: secret.secretReminderRepeatDays,
|
||||
secretReminderNote: secret.secretReminderNote,
|
||||
|
||||
@@ -259,6 +259,8 @@ export const secretQueueFactory = ({
|
||||
});
|
||||
}
|
||||
|
||||
const existingRecipients = await secretReminderRecipientsDAL.findUsersBySecretId(newSecret.id);
|
||||
|
||||
if (recipients?.length) {
|
||||
await secretReminderRecipientsDAL.transaction(async (tx) => {
|
||||
await secretReminderRecipientsDAL.delete({ secretId: newSecret.id }, tx);
|
||||
@@ -271,6 +273,8 @@ export const secretQueueFactory = ({
|
||||
tx
|
||||
);
|
||||
});
|
||||
} else if (existingRecipients) {
|
||||
await secretReminderRecipientsDAL.delete({ secretId: newSecret.id });
|
||||
}
|
||||
|
||||
await queueService.queue(
|
||||
@@ -306,12 +310,20 @@ export const secretQueueFactory = ({
|
||||
};
|
||||
|
||||
const handleSecretReminder = async ({ newSecret, oldSecret, projectId }: THandleReminderDTO) => {
|
||||
const { secretReminderRepeatDays, secretReminderNote } = newSecret;
|
||||
const { secretReminderRepeatDays, secretReminderNote, secretReminderRecipients } = newSecret;
|
||||
|
||||
const recipientsUpdated =
|
||||
secretReminderRecipients?.some(
|
||||
(newId) => !oldSecret.secretReminderRecipients?.find((oldId) => newId === oldId)
|
||||
) ||
|
||||
(secretReminderRecipients?.length !== oldSecret.secretReminderRecipients?.length &&
|
||||
secretReminderRepeatDays !== null);
|
||||
|
||||
if (newSecret.type !== SecretType.Personal && secretReminderRepeatDays !== undefined) {
|
||||
if (
|
||||
(secretReminderRepeatDays && oldSecret.secretReminderRepeatDays !== secretReminderRepeatDays) ||
|
||||
(secretReminderNote && oldSecret.secretReminderNote !== secretReminderNote)
|
||||
(secretReminderNote && oldSecret.secretReminderNote !== secretReminderNote) ||
|
||||
recipientsUpdated
|
||||
) {
|
||||
await addSecretReminder({
|
||||
oldSecret,
|
||||
|
||||
@@ -685,6 +685,7 @@ export const secretServiceFactory = ({
|
||||
...secret,
|
||||
workspace: projectId,
|
||||
environment,
|
||||
secretReminderRecipients: [],
|
||||
secretPath: groupedPaths[secret.folderId][0].path
|
||||
}))
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user