Skip to content

Commit

Permalink
Merge pull request #8 from diggerhq/feat/encrypt-variables
Browse files Browse the repository at this point in the history
Encrypt Variables securely
  • Loading branch information
motatoes authored Aug 5, 2024
2 parents ca70d8e + 0cde6bd commit cd57480
Show file tree
Hide file tree
Showing 10 changed files with 202 additions and 513 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,12 @@ import { Textarea } from "@/components/ui/textarea";
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 { AlertTriangle, Copy, Edit, LockKeyhole, Plus, Save, Trash, Unlock } from 'lucide-react';
import moment from 'moment';
import { useRouter } from 'next/navigation';
import { useState } from 'react';
import { toast } from 'sonner';

type TFVarTableProps = {
envVars: EnvVar[];
projectId: string;
};

const EmptyState: React.FC<{ onAddVariable: () => void }> = ({ onAddVariable }) => {
return (
<motion.div
Expand Down Expand Up @@ -50,7 +45,14 @@ const EmptyState: React.FC<{ onAddVariable: () => void }> = ({ onAddVariable })
);
};

export default function TFVarTable({ projectId, envVars }: TFVarTableProps) {
type TFVarTableProps = {
envVars: EnvVar[];
projectId: string;
orgId: string;
isAllowedSecrets: boolean;
};

export default function TFVarTable({ projectId, orgId, isAllowedSecrets, envVars }: TFVarTableProps) {
const [editingVar, setEditingVar] = useState<{ originalName: string, currentVar: EnvVar } | null>(null);
const [newVar, setNewVar] = useState<Omit<EnvVar, 'updated_at'>>({ name: '', value: '', is_secret: false });
const [bulkEditMode, setBulkEditMode] = useState(false);
Expand Down Expand Up @@ -83,7 +85,8 @@ export default function TFVarTable({ projectId, envVars }: TFVarTableProps) {
editingVar.currentVar.name,
editingVar.currentVar.value,
editingVar.currentVar.is_secret,
projectId
projectId,
orgId,
);
toast.success('Variable updated successfully');
setEditingVar(null);
Expand All @@ -104,7 +107,7 @@ export default function TFVarTable({ projectId, envVars }: TFVarTableProps) {
}
setIsLoading(true);
try {
await tfvarsOnUpdate(newVar.name, newVar.name, newVar.value, newVar.is_secret, projectId);
await tfvarsOnUpdate(newVar.name, newVar.name, newVar.value, newVar.is_secret, projectId, orgId);
toast.success('New variable added successfully');
setNewVar({ name: '', value: '', is_secret: false });
setShowAddForm(false);
Expand Down Expand Up @@ -141,7 +144,7 @@ export default function TFVarTable({ projectId, envVars }: TFVarTableProps) {
}

setIsLoading(true);
await tfvarsOnBulkUpdate(parsedVars, projectId);
await tfvarsOnBulkUpdate(parsedVars, projectId, orgId);
toast.success('Bulk update successful');
setBulkEditMode(false);
router.refresh();
Expand Down Expand Up @@ -305,15 +308,15 @@ export default function TFVarTable({ projectId, envVars }: TFVarTableProps) {
<div>
<Label htmlFor="varType">Variable Type</Label>
<Select
value={newVar.is_secret ? "secret" : "default"}
value={newVar.is_secret ? "secret" : "plain_text"}
onValueChange={(value) => setNewVar({ ...newVar, is_secret: value === "secret" })}
>
<SelectTrigger>
<SelectValue placeholder="Select type" />
</SelectTrigger>
<SelectContent>
<SelectItem value="default">Default</SelectItem>
<SelectItem value="secret">Secret</SelectItem>
<SelectItem value="plain_text">Plain Text</SelectItem>
<SelectItem value="secret" disabled={!isAllowedSecrets}>Secret</SelectItem>
</SelectContent>
</Select>
</div>
Expand All @@ -324,6 +327,14 @@ export default function TFVarTable({ projectId, envVars }: TFVarTableProps) {
{isLoading ? 'Adding...' : 'Add Variable'}
</Button>
</div>
{!isAllowedSecrets && (<div className="mt-4 flex justify-start">
<span className="flex items-center text-orange-400">
<AlertTriangle className="h-4 w-4 mr-2" />
<em className="text-sm italic">
To enable secrets creation, configure Secrets Key in your Organisation Settings
</em>
</span>
</div>)}
</Card>
)}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,12 @@ import TFVarTable from "./TFVarTable";

type TFVarsDetailsProps = {
projectId: string;
orgId: string;
isAllowedSecrets: boolean;
initialEnvVars: EnvVar[];
}

export default function TFVarsDetails({ projectId, initialEnvVars }: TFVarsDetailsProps) {
export default function TFVarsDetails({ projectId, orgId, isAllowedSecrets, initialEnvVars }: TFVarsDetailsProps) {
return (
<motion.div
initial={{ opacity: 0, y: 10 }}
Expand All @@ -23,12 +25,14 @@ export default function TFVarsDetails({ projectId, initialEnvVars }: TFVarsDetai
>
<Card className="w-full">
<CardHeader>
<CardTitle>Terraform Variables</CardTitle>
<CardDescription>Manage Terraform variables for project</CardDescription>
<CardTitle>Variables</CardTitle>
<CardDescription>Manage variables for project. They will be exposed in the job as environment variables.</CardDescription>
</CardHeader>
<CardContent>
<TFVarTable
projectId={projectId}
orgId={orgId}
isAllowedSecrets={isAllowedSecrets}
envVars={initialEnvVars}
/>
</CardContent>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ export default async function ProjectPage({ params }: { params: unknown }) {
const { projectSlug } = projectSlugParamSchema.parse(params);
const slimProject = await getSlimProjectBySlug(projectSlug);


return (
<div className="flex flex-col space-y-4 max-w-5xl mt-2">
<AllRunsDetails projectId={slimProject.id} projectSlug={projectSlug} />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// page.tsx
import { getAllEnvVars } from "@/data/admin/encryption";
import { getAllEnvVars, getOrganizationPublicKey } from "@/data/admin/env-vars";
import { getSlimProjectBySlug } from "@/data/user/projects";
import { projectSlugParamSchema } from "@/utils/zod-schemas/params";
import type { Metadata } from "next";
Expand All @@ -12,28 +12,25 @@ export async function generateMetadata({
const project = await getSlimProjectBySlug(projectSlug);

return {
title: `TFVars | ${project.name}`,
description: `Manage Terraform variables for ${project.name}`,
title: `Variables | ${project.name}`,
description: `Manage variables for ${project.name}`,
};
}

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);
const [envVars, publicKey] = await Promise.all([
getAllEnvVars(project.id),
getOrganizationPublicKey(project.organization_id)
]);

return (
<div className="flex flex-col space-y-4 max-w-5xl mt-2">
<TFVarsDetails
projectId={project.id}
orgId={project.organization_id}
isAllowedSecrets={Boolean(publicKey)}
initialEnvVars={envVars}
/>
</div>
Expand Down
163 changes: 0 additions & 163 deletions src/data/admin/encryption.ts

This file was deleted.

Loading

0 comments on commit cd57480

Please sign in to comment.