validate([ 'image' => 'required|string', 'folder' => 'required|string|max:80', 'filename' => 'required|string|max:200', ]); $imageData = $request->image; $parts = explode(';base64,', $imageData); $typePart = explode('image/', $parts[0]); $extension = $typePart[1] ?? 'png'; // Sanitize extension $extension = preg_replace('/[^a-z0-9]/', '', strtolower($extension)); if (!in_array($extension, ['png', 'jpg', 'jpeg', 'webp', 'gif'])) { $extension = 'png'; } $imageBinary = base64_decode($parts[1] ?? ''); if (!$imageBinary) { return response()->json(['success' => false, 'message' => 'Invalid image data'], 422); } $folder = trim($request->folder, '/'); $fileName = $request->filename . '.' . $extension; $fullPath = $folder . '/' . $fileName; Storage::disk('public')->put($fullPath, $imageBinary); return response()->json([ 'success' => true, 'path' => $fullPath, 'url' => asset('storage/' . $fullPath), ]); } }