Skip to content

Commit cd57480

Browse files
authored
Merge pull request #8 from diggerhq/feat/encrypt-variables
Encrypt Variables securely
2 parents ca70d8e + 0cde6bd commit cd57480

File tree

10 files changed

+202
-513
lines changed

10 files changed

+202
-513
lines changed

src/app/(dynamic-pages)/(authenticated-pages)/(application-pages)/project/[projectSlug]/(specific-project-pages)/TFVarTable.tsx

+24-13
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,12 @@ import { Textarea } from "@/components/ui/textarea";
1212
import { tfvarsOnBulkUpdate, tfvarsOnDelete, tfvarsOnUpdate } from "@/data/user/tfvars";
1313
import { EnvVar } from "@/types/userTypes";
1414
import { motion } from 'framer-motion';
15-
import { Copy, Edit, LockKeyhole, Plus, Save, Trash, Unlock } from 'lucide-react';
15+
import { AlertTriangle, Copy, Edit, LockKeyhole, Plus, Save, Trash, Unlock } from 'lucide-react';
1616
import moment from 'moment';
1717
import { useRouter } from 'next/navigation';
1818
import { useState } from 'react';
1919
import { toast } from 'sonner';
2020

21-
type TFVarTableProps = {
22-
envVars: EnvVar[];
23-
projectId: string;
24-
};
25-
2621
const EmptyState: React.FC<{ onAddVariable: () => void }> = ({ onAddVariable }) => {
2722
return (
2823
<motion.div
@@ -50,7 +45,14 @@ const EmptyState: React.FC<{ onAddVariable: () => void }> = ({ onAddVariable })
5045
);
5146
};
5247

53-
export default function TFVarTable({ projectId, envVars }: TFVarTableProps) {
48+
type TFVarTableProps = {
49+
envVars: EnvVar[];
50+
projectId: string;
51+
orgId: string;
52+
isAllowedSecrets: boolean;
53+
};
54+
55+
export default function TFVarTable({ projectId, orgId, isAllowedSecrets, envVars }: TFVarTableProps) {
5456
const [editingVar, setEditingVar] = useState<{ originalName: string, currentVar: EnvVar } | null>(null);
5557
const [newVar, setNewVar] = useState<Omit<EnvVar, 'updated_at'>>({ name: '', value: '', is_secret: false });
5658
const [bulkEditMode, setBulkEditMode] = useState(false);
@@ -83,7 +85,8 @@ export default function TFVarTable({ projectId, envVars }: TFVarTableProps) {
8385
editingVar.currentVar.name,
8486
editingVar.currentVar.value,
8587
editingVar.currentVar.is_secret,
86-
projectId
88+
projectId,
89+
orgId,
8790
);
8891
toast.success('Variable updated successfully');
8992
setEditingVar(null);
@@ -104,7 +107,7 @@ export default function TFVarTable({ projectId, envVars }: TFVarTableProps) {
104107
}
105108
setIsLoading(true);
106109
try {
107-
await tfvarsOnUpdate(newVar.name, newVar.name, newVar.value, newVar.is_secret, projectId);
110+
await tfvarsOnUpdate(newVar.name, newVar.name, newVar.value, newVar.is_secret, projectId, orgId);
108111
toast.success('New variable added successfully');
109112
setNewVar({ name: '', value: '', is_secret: false });
110113
setShowAddForm(false);
@@ -141,7 +144,7 @@ export default function TFVarTable({ projectId, envVars }: TFVarTableProps) {
141144
}
142145

143146
setIsLoading(true);
144-
await tfvarsOnBulkUpdate(parsedVars, projectId);
147+
await tfvarsOnBulkUpdate(parsedVars, projectId, orgId);
145148
toast.success('Bulk update successful');
146149
setBulkEditMode(false);
147150
router.refresh();
@@ -305,15 +308,15 @@ export default function TFVarTable({ projectId, envVars }: TFVarTableProps) {
305308
<div>
306309
<Label htmlFor="varType">Variable Type</Label>
307310
<Select
308-
value={newVar.is_secret ? "secret" : "default"}
311+
value={newVar.is_secret ? "secret" : "plain_text"}
309312
onValueChange={(value) => setNewVar({ ...newVar, is_secret: value === "secret" })}
310313
>
311314
<SelectTrigger>
312315
<SelectValue placeholder="Select type" />
313316
</SelectTrigger>
314317
<SelectContent>
315-
<SelectItem value="default">Default</SelectItem>
316-
<SelectItem value="secret">Secret</SelectItem>
318+
<SelectItem value="plain_text">Plain Text</SelectItem>
319+
<SelectItem value="secret" disabled={!isAllowedSecrets}>Secret</SelectItem>
317320
</SelectContent>
318321
</Select>
319322
</div>
@@ -324,6 +327,14 @@ export default function TFVarTable({ projectId, envVars }: TFVarTableProps) {
324327
{isLoading ? 'Adding...' : 'Add Variable'}
325328
</Button>
326329
</div>
330+
{!isAllowedSecrets && (<div className="mt-4 flex justify-start">
331+
<span className="flex items-center text-orange-400">
332+
<AlertTriangle className="h-4 w-4 mr-2" />
333+
<em className="text-sm italic">
334+
To enable secrets creation, configure Secrets Key in your Organisation Settings
335+
</em>
336+
</span>
337+
</div>)}
327338
</Card>
328339
)}
329340

src/app/(dynamic-pages)/(authenticated-pages)/(application-pages)/project/[projectSlug]/(specific-project-pages)/TFVarsDetails.tsx

+7-3
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,12 @@ import TFVarTable from "./TFVarTable";
1010

1111
type TFVarsDetailsProps = {
1212
projectId: string;
13+
orgId: string;
14+
isAllowedSecrets: boolean;
1315
initialEnvVars: EnvVar[];
1416
}
1517

16-
export default function TFVarsDetails({ projectId, initialEnvVars }: TFVarsDetailsProps) {
18+
export default function TFVarsDetails({ projectId, orgId, isAllowedSecrets, initialEnvVars }: TFVarsDetailsProps) {
1719
return (
1820
<motion.div
1921
initial={{ opacity: 0, y: 10 }}
@@ -23,12 +25,14 @@ export default function TFVarsDetails({ projectId, initialEnvVars }: TFVarsDetai
2325
>
2426
<Card className="w-full">
2527
<CardHeader>
26-
<CardTitle>Terraform Variables</CardTitle>
27-
<CardDescription>Manage Terraform variables for project</CardDescription>
28+
<CardTitle>Variables</CardTitle>
29+
<CardDescription>Manage variables for project. They will be exposed in the job as environment variables.</CardDescription>
2830
</CardHeader>
2931
<CardContent>
3032
<TFVarTable
3133
projectId={projectId}
34+
orgId={orgId}
35+
isAllowedSecrets={isAllowedSecrets}
3236
envVars={initialEnvVars}
3337
/>
3438
</CardContent>

src/app/(dynamic-pages)/(authenticated-pages)/(application-pages)/project/[projectSlug]/(specific-project-pages)/page.tsx

-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ export default async function ProjectPage({ params }: { params: unknown }) {
2525
const { projectSlug } = projectSlugParamSchema.parse(params);
2626
const slimProject = await getSlimProjectBySlug(projectSlug);
2727

28-
2928
return (
3029
<div className="flex flex-col space-y-4 max-w-5xl mt-2">
3130
<AllRunsDetails projectId={slimProject.id} projectSlug={projectSlug} />

src/app/(dynamic-pages)/(authenticated-pages)/(application-pages)/project/[projectSlug]/(specific-project-pages)/tfvars/page.tsx

+9-12
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// page.tsx
2-
import { getAllEnvVars } from "@/data/admin/encryption";
2+
import { getAllEnvVars, getOrganizationPublicKey } from "@/data/admin/env-vars";
33
import { getSlimProjectBySlug } from "@/data/user/projects";
44
import { projectSlugParamSchema } from "@/utils/zod-schemas/params";
55
import type { Metadata } from "next";
@@ -12,28 +12,25 @@ export async function generateMetadata({
1212
const project = await getSlimProjectBySlug(projectSlug);
1313

1414
return {
15-
title: `TFVars | ${project.name}`,
16-
description: `Manage Terraform variables for ${project.name}`,
15+
title: `Variables | ${project.name}`,
16+
description: `Manage variables for ${project.name}`,
1717
};
1818
}
1919

2020
export default async function TFVarsPage({ params }: { params: unknown }) {
2121
const { projectSlug } = projectSlugParamSchema.parse(params);
2222
const project = await getSlimProjectBySlug(projectSlug);
23-
24-
const MASTER_PASSWORD = process.env.MASTER_PASSWORD;
25-
const ENCRYPTION_SALT = process.env.ENCRYPTION_SALT;
26-
27-
if (!MASTER_PASSWORD || !ENCRYPTION_SALT) {
28-
throw new Error('MASTER_PASSWORD or ENCRYPTION_SALT is not set');
29-
}
30-
31-
const envVars = await getAllEnvVars(project.id);
23+
const [envVars, publicKey] = await Promise.all([
24+
getAllEnvVars(project.id),
25+
getOrganizationPublicKey(project.organization_id)
26+
]);
3227

3328
return (
3429
<div className="flex flex-col space-y-4 max-w-5xl mt-2">
3530
<TFVarsDetails
3631
projectId={project.id}
32+
orgId={project.organization_id}
33+
isAllowedSecrets={Boolean(publicKey)}
3734
initialEnvVars={envVars}
3835
/>
3936
</div>

src/data/admin/encryption.ts

-163
This file was deleted.

0 commit comments

Comments
 (0)