From 22f617a01ae8ae193b08940896b3b9fbf65a05d9 Mon Sep 17 00:00:00 2001 From: Igor Zalutski Date: Fri, 2 Aug 2024 20:09:09 +0100 Subject: [PATCH] Disable secret creation if no secret key --- .../(specific-project-pages)/TFVarTable.tsx | 14 ++++++-- .../(specific-project-pages)/tfvars/page.tsx | 7 ---- src/data/admin/env-vars.ts | 34 +++++++++++++------ 3 files changed, 35 insertions(+), 20 deletions(-) diff --git a/src/app/(dynamic-pages)/(authenticated-pages)/(application-pages)/project/[projectSlug]/(specific-project-pages)/TFVarTable.tsx b/src/app/(dynamic-pages)/(authenticated-pages)/(application-pages)/project/[projectSlug]/(specific-project-pages)/TFVarTable.tsx index af0c41d8..78a3003b 100644 --- a/src/app/(dynamic-pages)/(authenticated-pages)/(application-pages)/project/[projectSlug]/(specific-project-pages)/TFVarTable.tsx +++ b/src/app/(dynamic-pages)/(authenticated-pages)/(application-pages)/project/[projectSlug]/(specific-project-pages)/TFVarTable.tsx @@ -9,13 +9,14 @@ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@ import { Separator } from "@/components/ui/separator"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"; import { Textarea } from "@/components/ui/textarea"; +import { getProjectPublicKey } from "@/data/admin/env-vars"; import { tfvarsOnBulkUpdate, tfvarsOnDelete, tfvarsOnUpdate } from "@/data/user/tfvars"; import { EnvVar } from "@/types/userTypes"; import { motion } from 'framer-motion'; import { Copy, Edit, LockKeyhole, Plus, Save, Trash, Unlock } from 'lucide-react'; import moment from 'moment'; import { useRouter } from 'next/navigation'; -import { useState } from 'react'; +import { useEffect, useState } from 'react'; import { toast } from 'sonner'; type TFVarTableProps = { @@ -57,8 +58,17 @@ export default function TFVarTable({ projectId, envVars }: TFVarTableProps) { const [bulkEditValue, setBulkEditValue] = useState(''); const [isLoading, setIsLoading] = useState(false); const [showAddForm, setShowAddForm] = useState(false); + const [canCreateSecrets, setCanCreateSecrets] = useState(true); const router = useRouter(); + useEffect(() => { + getProjectPublicKey(projectId).then(key => { + if (!key) { + setCanCreateSecrets(false); + } + }) + }); + const handleEdit = (envVar: EnvVar) => { setEditingVar({ originalName: envVar.name, @@ -313,7 +323,7 @@ export default function TFVarTable({ projectId, envVars }: TFVarTableProps) { Plain Text - Secret + Secret diff --git a/src/app/(dynamic-pages)/(authenticated-pages)/(application-pages)/project/[projectSlug]/(specific-project-pages)/tfvars/page.tsx b/src/app/(dynamic-pages)/(authenticated-pages)/(application-pages)/project/[projectSlug]/(specific-project-pages)/tfvars/page.tsx index 499d1781..354808d7 100644 --- a/src/app/(dynamic-pages)/(authenticated-pages)/(application-pages)/project/[projectSlug]/(specific-project-pages)/tfvars/page.tsx +++ b/src/app/(dynamic-pages)/(authenticated-pages)/(application-pages)/project/[projectSlug]/(specific-project-pages)/tfvars/page.tsx @@ -21,13 +21,6 @@ export default async function TFVarsPage({ params }: { params: unknown }) { const { projectSlug } = projectSlugParamSchema.parse(params); const project = await getSlimProjectBySlug(projectSlug); - const MASTER_PASSWORD = process.env.MASTER_PASSWORD; - const ENCRYPTION_SALT = process.env.ENCRYPTION_SALT; - - if (!MASTER_PASSWORD || !ENCRYPTION_SALT) { - throw new Error('MASTER_PASSWORD or ENCRYPTION_SALT is not set'); - } - const envVars = await getAllEnvVars(project.id); return ( diff --git a/src/data/admin/env-vars.ts b/src/data/admin/env-vars.ts index f0f7c589..7f661a82 100644 --- a/src/data/admin/env-vars.ts +++ b/src/data/admin/env-vars.ts @@ -1,3 +1,5 @@ +'use server'; + import { supabaseAdminClient } from '@/supabase-clients/admin/supabaseAdminClient'; import { EnvVar } from '@/types/userTypes'; import { constants, publicEncrypt } from 'crypto'; @@ -6,17 +8,7 @@ export async function encryptSecretWithPublicKey( text: string, projectId: string, ): Promise { - const { data: orgData } = await supabaseAdminClient - .from('projects') - .select('organization_id') - .eq('id', projectId) - .single(); - const { data: publicKeyData } = await supabaseAdminClient - .from('organizations') - .select('public_key') - .eq('id', orgData?.organization_id || '') - .single(); - const publicKey = publicKeyData?.public_key; + const publicKey = await getProjectPublicKey(projectId); if (!publicKey) { console.error('No secrets key in the org'); throw new Error('No secrets key in the org'); @@ -33,6 +25,26 @@ export async function encryptSecretWithPublicKey( return encrypted.toString('base64'); } +export async function getProjectPublicKey( + projectId: string, +): Promise { + const { data: orgData } = await supabaseAdminClient + .from('projects') + .select('organization_id') + .eq('id', projectId) + .single(); + const { data: publicKeyData } = await supabaseAdminClient + .from('organizations') + .select('public_key') + .eq('id', orgData?.organization_id || '') + .single(); + if (publicKeyData?.public_key) { + return publicKeyData.public_key; + } else { + return null; + } +} + export async function storeEnvVar( projectId: string, name: string,