mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-09-22 13:39:35 +00:00
feat: only fetch secret if password wasn't set on initial load
This commit is contained in:
@@ -21,7 +21,6 @@ export const SecretSharingSchema = z.object({
|
|||||||
expiresAfterViews: z.number().nullable().optional(),
|
expiresAfterViews: z.number().nullable().optional(),
|
||||||
accessType: z.string().default("anyone"),
|
accessType: z.string().default("anyone"),
|
||||||
name: z.string().nullable().optional(),
|
name: z.string().nullable().optional(),
|
||||||
password: z.string().nullable().optional(),
|
|
||||||
lastViewedAt: z.date().nullable().optional()
|
lastViewedAt: z.date().nullable().optional()
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import bcrypt from "bcrypt";
|
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
import { SecretSharingSchema } from "@app/db/schemas";
|
import { SecretSharingSchema } from "@app/db/schemas";
|
||||||
@@ -64,7 +63,6 @@ export const registerSecretSharingRouter = async (server: FastifyZodProvider) =>
|
|||||||
response: {
|
response: {
|
||||||
200: SecretSharingSchema.pick({
|
200: SecretSharingSchema.pick({
|
||||||
encryptedValue: true,
|
encryptedValue: true,
|
||||||
password: true,
|
|
||||||
iv: true,
|
iv: true,
|
||||||
tag: true,
|
tag: true,
|
||||||
expiresAt: true,
|
expiresAt: true,
|
||||||
@@ -81,12 +79,14 @@ export const registerSecretSharingRouter = async (server: FastifyZodProvider) =>
|
|||||||
hashedHex: req.query.hashedHex,
|
hashedHex: req.query.hashedHex,
|
||||||
orgId: req.permission?.orgId
|
orgId: req.permission?.orgId
|
||||||
});
|
});
|
||||||
if (!sharedSecret) return undefined;
|
|
||||||
|
// only return secret if it exists and has no password set
|
||||||
|
if (!sharedSecret || sharedSecret.password) return undefined;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
encryptedValue: sharedSecret.encryptedValue,
|
encryptedValue: sharedSecret.encryptedValue,
|
||||||
iv: sharedSecret.iv,
|
iv: sharedSecret.iv,
|
||||||
tag: sharedSecret.tag,
|
tag: sharedSecret.tag,
|
||||||
password: sharedSecret.password,
|
|
||||||
expiresAt: sharedSecret.expiresAt,
|
expiresAt: sharedSecret.expiresAt,
|
||||||
expiresAfterViews: sharedSecret.expiresAfterViews,
|
expiresAfterViews: sharedSecret.expiresAfterViews,
|
||||||
accessType: sharedSecret.accessType,
|
accessType: sharedSecret.accessType,
|
||||||
@@ -110,8 +110,15 @@ export const registerSecretSharingRouter = async (server: FastifyZodProvider) =>
|
|||||||
hashedHex: z.string()
|
hashedHex: z.string()
|
||||||
}),
|
}),
|
||||||
response: {
|
response: {
|
||||||
200: z.object({
|
200: SecretSharingSchema.pick({
|
||||||
isValid: z.boolean()
|
encryptedValue: true,
|
||||||
|
iv: true,
|
||||||
|
tag: true,
|
||||||
|
expiresAt: true,
|
||||||
|
expiresAfterViews: true,
|
||||||
|
accessType: true,
|
||||||
|
}).extend({
|
||||||
|
orgName: z.string().optional()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -119,22 +126,24 @@ export const registerSecretSharingRouter = async (server: FastifyZodProvider) =>
|
|||||||
const { id } = req.params;
|
const { id } = req.params;
|
||||||
const { password, hashedHex } = req.body;
|
const { password, hashedHex } = req.body;
|
||||||
|
|
||||||
const sharedSecret = await req.server.services.secretSharing.getActiveSharedSecretById({
|
const sharedSecret = await req.server.services.secretSharing.validateSecretPassword({
|
||||||
sharedSecretId: id,
|
sharedSecretId: id,
|
||||||
hashedHex,
|
hashedHex,
|
||||||
orgId: req.permission?.orgId
|
orgId: req.permission?.orgId,
|
||||||
|
password
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!sharedSecret) {
|
if (!sharedSecret) return undefined;
|
||||||
return { isValid: false };
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sharedSecret.password) {
|
return {
|
||||||
const isMatch = await bcrypt.compare(password, sharedSecret.password);
|
encryptedValue: sharedSecret.encryptedValue,
|
||||||
return { isValid: isMatch };
|
iv: sharedSecret.iv,
|
||||||
}
|
tag: sharedSecret.tag,
|
||||||
|
expiresAt: sharedSecret.expiresAt,
|
||||||
return { isValid: false };
|
expiresAfterViews: sharedSecret.expiresAfterViews,
|
||||||
|
accessType: sharedSecret.accessType,
|
||||||
|
orgName: sharedSecret.orgName
|
||||||
|
};
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,8 @@ import {
|
|||||||
TCreateSharedSecretDTO,
|
TCreateSharedSecretDTO,
|
||||||
TDeleteSharedSecretDTO,
|
TDeleteSharedSecretDTO,
|
||||||
TGetActiveSharedSecretByIdDTO,
|
TGetActiveSharedSecretByIdDTO,
|
||||||
TGetSharedSecretsDTO
|
TGetSharedSecretsDTO,
|
||||||
|
TValidateActiveSharedSecretDTO
|
||||||
} from "./secret-sharing-types";
|
} from "./secret-sharing-types";
|
||||||
|
|
||||||
type TSecretSharingServiceFactoryDep = {
|
type TSecretSharingServiceFactoryDep = {
|
||||||
@@ -108,8 +109,9 @@ export const secretSharingServiceFactory = ({
|
|||||||
throw new BadRequestError({ message: "Shared secret value too long" });
|
throw new BadRequestError({ message: "Shared secret value too long" });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const hashedPassword = password ? await bcrypt.hash(password, 10) : null;
|
||||||
const newSharedSecret = await secretSharingDAL.create({
|
const newSharedSecret = await secretSharingDAL.create({
|
||||||
password,
|
password: hashedPassword,
|
||||||
encryptedValue,
|
encryptedValue,
|
||||||
hashedHex,
|
hashedHex,
|
||||||
iv,
|
iv,
|
||||||
@@ -211,6 +213,22 @@ export const secretSharingServiceFactory = ({
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const validateSecretPassword = async ({
|
||||||
|
sharedSecretId,
|
||||||
|
hashedHex,
|
||||||
|
orgId,
|
||||||
|
password
|
||||||
|
}: TValidateActiveSharedSecretDTO) => {
|
||||||
|
const sharedSecret = await getActiveSharedSecretById({ sharedSecretId, hashedHex, orgId });
|
||||||
|
|
||||||
|
if (!sharedSecret || !sharedSecret.password) return undefined;
|
||||||
|
|
||||||
|
const isMatch = await bcrypt.compare(password, sharedSecret.password);
|
||||||
|
|
||||||
|
if (!isMatch) return undefined;
|
||||||
|
return sharedSecret
|
||||||
|
};
|
||||||
|
|
||||||
const deleteSharedSecretById = async (deleteSharedSecretInput: TDeleteSharedSecretDTO) => {
|
const deleteSharedSecretById = async (deleteSharedSecretInput: TDeleteSharedSecretDTO) => {
|
||||||
const { actor, actorId, orgId, actorAuthMethod, actorOrgId, sharedSecretId } = deleteSharedSecretInput;
|
const { actor, actorId, orgId, actorAuthMethod, actorOrgId, sharedSecretId } = deleteSharedSecretInput;
|
||||||
const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId);
|
const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId);
|
||||||
@@ -224,6 +242,7 @@ export const secretSharingServiceFactory = ({
|
|||||||
createPublicSharedSecret,
|
createPublicSharedSecret,
|
||||||
getSharedSecrets,
|
getSharedSecrets,
|
||||||
deleteSharedSecretById,
|
deleteSharedSecretById,
|
||||||
getActiveSharedSecretById
|
getActiveSharedSecretById,
|
||||||
|
validateSecretPassword
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -35,6 +35,10 @@ export type TGetActiveSharedSecretByIdDTO = {
|
|||||||
orgId?: string;
|
orgId?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type TValidateActiveSharedSecretDTO = TGetActiveSharedSecretByIdDTO & {
|
||||||
|
password: string;
|
||||||
|
};
|
||||||
|
|
||||||
export type TCreateSharedSecretDTO = TSharedSecretPermission & TCreatePublicSharedSecretDTO;
|
export type TCreateSharedSecretDTO = TSharedSecretPermission & TCreatePublicSharedSecretDTO;
|
||||||
|
|
||||||
export type TDeleteSharedSecretDTO = {
|
export type TDeleteSharedSecretDTO = {
|
||||||
|
|||||||
Reference in New Issue
Block a user