feat: only fetch secret if password wasn't set on initial load

This commit is contained in:
lemmyMwaura
2024-08-07 16:06:37 +03:00
parent 406da1b5f0
commit 56f2a3afa4
4 changed files with 52 additions and 21 deletions

View File

@@ -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()
}); });

View File

@@ -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
};
} }
}); });

View File

@@ -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
}; };
}; };

View File

@@ -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 = {