fix: replace hardcoded edit secret with session auth (#2608)

## Summary
- Replace hardcoded `"codeflash-edit-2025"` string authentication in the
`save-modified-code` API route with Auth0 session check
- Remove the secret prompt modal from the Monaco diff viewer — editing
is now gated by the user's existing login session
- Remove unused `Lock` import, dead `console.log`, and unused `result`
variable

## Test plan
- [ ] Verify the edit code button works without prompting for a secret
- [ ] Verify saving modified code succeeds for logged-in users
- [ ] Verify unauthenticated requests to
`/api/traces/:id/save-modified-code` return 401
This commit is contained in:
Kevin Turcios 2026-04-14 21:59:58 -05:00 committed by GitHub
parent e5374c3f50
commit 4c9cdff1b0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 15 additions and 72 deletions

View file

@ -1,18 +1,19 @@
import { NextRequest, NextResponse } from "next/server"
import { Prisma } from "@prisma/client"
import { prisma } from "@/lib/prisma"
import { auth0 } from "@/lib/auth0"
export async function POST(request: NextRequest, props: { params: Promise<{ trace_id: string }> }) {
const params = await props.params
try {
const session = await auth0.getSession()
if (!session?.user?.sub) {
return NextResponse.json({ error: "Unauthorized" }, { status: 401 })
}
const { trace_id } = params
const body = await request.json()
const { fileKey, modifiedCode, secret } = body
if (secret !== "codeflash-edit-2025") {
//console.log("Secret mismatch. Expected: codeflash-edit-2025, Received:", secret)
return NextResponse.json({ error: "Invalid secret" }, { status: 401 })
}
const { fileKey, modifiedCode } = body
if (!trace_id || !fileKey || !modifiedCode) {
return NextResponse.json({ error: "Missing required fields" }, { status: 400 })
@ -72,7 +73,7 @@ export async function POST(request: NextRequest, props: { params: Promise<{ trac
}
// Update the record with both experiment_metadata and metadata
const result = await prisma.optimization_features.update({
await prisma.optimization_features.update({
where: { trace_id },
data: {
experiment_metadata: updatedExperimentMetadata,
@ -80,8 +81,6 @@ export async function POST(request: NextRequest, props: { params: Promise<{ trac
},
})
console.log("Database update successful for trace:", trace_id)
return NextResponse.json({
success: true,
message: "Modified code saved successfully",

View file

@ -14,7 +14,6 @@ import {
FileText,
GitPullRequest,
Loader2,
Lock,
Monitor,
Save,
Smartphone,
@ -57,8 +56,6 @@ const MonacoDiffViewer: React.FC<MonacoDiffViewerProps> = ({
const [showOptimizationQuality, setShowOptimizationQuality] = useState(false)
const [showOptimizationExplanation, setShowOptimizationExplanation] = useState(false)
const [isEditing, setIsEditing] = useState(false)
const [editSecret, setEditSecret] = useState("")
const [showSecretPrompt, setShowSecretPrompt] = useState(false)
const [currentEdit, setCurrentEdit] = useState<{ [key: string]: string }>({})
const [saveStatus, setSaveStatus] = useState<"idle" | "saving" | "saved" | "error">("idle")
const [savedChanges, setSavedChanges] = useState<{ [key: string]: string }>({})
@ -146,23 +143,13 @@ const MonacoDiffViewer: React.FC<MonacoDiffViewerProps> = ({
}, [prCommentFields])
const handleEditClick = () => {
setShowSecretPrompt(true)
}
const handleSecretSubmit = () => {
if (editSecret === "codeflash-edit-2025") {
setIsEditing(true)
setShowSecretPrompt(false)
// Initialize current edit with current content if not already set
if (activeFileKey && diffContents?.[activeFileKey] && !currentEdit[activeFileKey]) {
setCurrentEdit(prev => ({
...prev,
[activeFileKey]:
diffContents[activeFileKey].newContent || diffContents[activeFileKey].oldContent || "",
}))
}
} else {
alert("Invalid secret!")
setIsEditing(true)
if (activeFileKey && diffContents?.[activeFileKey] && !currentEdit[activeFileKey]) {
setCurrentEdit(prev => ({
...prev,
[activeFileKey]:
diffContents[activeFileKey].newContent || diffContents[activeFileKey].oldContent || "",
}))
}
}
@ -179,7 +166,6 @@ const MonacoDiffViewer: React.FC<MonacoDiffViewerProps> = ({
body: JSON.stringify({
fileKey: activeFileKey,
modifiedCode: currentEdit[activeFileKey],
secret: editSecret,
}),
})
@ -215,7 +201,6 @@ const MonacoDiffViewer: React.FC<MonacoDiffViewerProps> = ({
const handleCancelEdit = () => {
setIsEditing(false)
setEditSecret("")
// Revert changes for current file
if (activeFileKey) {
setCurrentEdit(prev => {
@ -792,47 +777,6 @@ const MonacoDiffViewer: React.FC<MonacoDiffViewerProps> = ({
</div>
)}
</div>
{/* Secret Prompt Modal - Mobile Optimized */}
{showSecretPrompt && (
<div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 p-4">
<div className="bg-slate-800 rounded-lg p-4 sm:p-6 max-w-md w-full mx-4">
<div className="flex items-center gap-2 sm:gap-3 mb-3 sm:mb-4">
<Lock className="h-4 w-4 sm:h-5 sm:w-5 text-amber-400 flex-shrink-0" />
<h3 className="text-base sm:text-lg font-semibold text-white">Enter Edit Secret</h3>
</div>
<p className="text-slate-300 text-xs sm:text-sm mb-3 sm:mb-4">
Please enter the secret key to enable code editing.
</p>
<input
type="password"
placeholder="Enter secret..."
value={editSecret}
onChange={e => setEditSecret(e.target.value)}
onKeyDown={e => e.key === "Enter" && handleSecretSubmit()}
className="w-full px-3 py-2 bg-slate-700 border border-slate-600 rounded-lg text-white placeholder-slate-400 focus:outline-none focus:ring-2 focus:ring-purple-500 focus:border-transparent mb-3 sm:mb-4 text-sm sm:text-base"
autoFocus
/>
<div className="flex gap-2 sm:gap-3 justify-end">
<button
onClick={() => {
setShowSecretPrompt(false)
setEditSecret("")
}}
className="px-3 sm:px-4 py-1.5 sm:py-2 text-slate-300 hover:text-white transition-colors text-sm sm:text-base"
>
Cancel
</button>
<button
onClick={handleSecretSubmit}
className="px-3 sm:px-4 py-1.5 sm:py-2 bg-purple-600 hover:bg-purple-700 text-white rounded-lg transition-colors text-sm sm:text-base"
>
Unlock
</button>
</div>
</div>
</div>
)}
</div>
)
}