Skip to content

Staging #915

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 106 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
106 commits
Select commit Hold shift + click to select a range
70f4bba
fix set node attributes
Anchel123 Apr 23, 2025
dc86024
mid restyle + code refactor
Anchel123 Apr 24, 2025
4eea5a1
mid restyle + code refactor
Anchel123 Apr 24, 2025
70935cb
Enhance QuerySettings component with tooltips for Timeout and Limit, …
Anchel123 Apr 24, 2025
a00b943
Enhance login and query settings functionality by adding localStorage…
Anchel123 Apr 24, 2025
01a22ea
add tutorial (#879)
Naseem77 Apr 24, 2025
960c337
Implement role-based query handling for Read-Only users across graph …
Anchel123 Apr 27, 2025
64e13c8
fix duplicate
Anchel123 Apr 27, 2025
ceb0c21
fix api vulnerability
Naseem77 Apr 28, 2025
9d94898
update middleware
Naseem77 Apr 28, 2025
93984a2
remove middleware for API CORS handling
Anchel123 Apr 28, 2025
1944c6f
Merge branch 'fix-vulnerability' of https://github.com/FalkorDB/falko…
Anchel123 Apr 28, 2025
7c603ca
Implement new button interactions and enhance settings management in …
Anchel123 Apr 28, 2025
4e0da61
Add TableView page object model and corresponding tests
Anchel123 Apr 28, 2025
06880ee
add test on read only user and fix eslint errors
Anchel123 Apr 28, 2025
69df711
Remove 'only' from admin table view validation test to ensure it runs…
Anchel123 Apr 28, 2025
c33af8c
fix data panel state handle and add test
Anchel123 Apr 28, 2025
d0178c5
Merge pull request #905 from FalkorDB/fix-roles-premissions
Anchel123 Apr 28, 2025
8fd266c
Merge branch 'staging' into add-graph-test-for-read-only
Anchel123 Apr 28, 2025
06b651e
Merge pull request #909 from FalkorDB/fix-vulnerability
Anchel123 Apr 28, 2025
10c1410
Merge pull request #906 from FalkorDB/fix-query-settings
Anchel123 Apr 28, 2025
b72aa7d
Merge branch 'staging' into save-query-settings-to-local-storae
Anchel123 Apr 28, 2025
7b3666d
Merge pull request #908 from FalkorDB/fix-duplicate-graph
Anchel123 Apr 28, 2025
47bdd30
Merge branch 'staging' into fix-set-node-attributes
Anchel123 Apr 28, 2025
fee2624
Merge pull request #902 from FalkorDB/tutorialtests
Anchel123 Apr 28, 2025
5ea1f29
Merge pull request #907 from FalkorDB/save-query-settings-to-local-st…
Anchel123 Apr 28, 2025
42f4705
Merge branch 'staging' into fix-set-node-attributes
Anchel123 Apr 28, 2025
95231fb
Merge branch 'staging' into add-data-view-test
barakb Apr 28, 2025
d012ea4
Merge branch 'staging' into add-graph-test-for-read-only
barakb Apr 28, 2025
94d5f22
Remove 'only' from data panel test for adding attributes to ensure it…
Anchel123 Apr 29, 2025
9991fb3
mid commit
Anchel123 Apr 30, 2025
aa510de
commit
Anchel123 May 4, 2025
cf452b3
commit
Anchel123 May 5, 2025
24946de
fix labels
Anchel123 May 5, 2025
6a90632
Merge pull request #914 from FalkorDB/fix-set-node-attributes
Anchel123 May 5, 2025
d6e9cd0
Merge pull request #913 from FalkorDB/add-graph-test-for-read-only
Anchel123 May 5, 2025
ec0e59f
Merge pull request #912 from FalkorDB/add-data-view-test
Anchel123 May 5, 2025
59bfa28
Update version to 2.0.0 in package.json and package-lock.json
Anchel123 May 5, 2025
05b02a5
Merge remote-tracking branch 'origin/staging' into replace-browser-ui
Anchel123 May 6, 2025
0617d3b
mid commit
Anchel123 May 8, 2025
6496139
Merge pull request #919 from FalkorDB/bump-version-2.0.0
barakb May 11, 2025
04ca161
mid
Anchel123 May 12, 2025
b205f73
fix build
Anchel123 May 12, 2025
d957adf
Merge branch 'staging' into replace-browser-ui
Anchel123 May 12, 2025
cdeec7d
Refactor Combobox and GraphPage for improved testability and maintain…
Anchel123 May 12, 2025
ddda45c
instead of scroll added pagination and add tabs to show editor and me…
Anchel123 May 13, 2025
1b98e8e
Update styles and tooltip component for improved UI consistency
Anchel123 May 14, 2025
e0e693f
Enhance GraphView component with improved display of graph information
Anchel123 May 14, 2025
f8cc54f
Merge pull request #918 from FalkorDB/replace-browser-ui
Anchel123 May 14, 2025
9988d41
Enhance Graph model with generic Category types for improved type safety
Anchel123 May 14, 2025
4a81785
fix build and apply graph changes on schema
Anchel123 May 14, 2025
ba05b57
Merge branch 'staging' into fix-tooltips
barakb May 14, 2025
2fa1712
Merge branch 'staging' into fix-query-history
barakb May 14, 2025
e353b1e
Merge branch 'staging' into label-relation-toggle-indicator
barakb May 14, 2025
e544c38
Add GraphDetails component for improved graph information display
Anchel123 May 14, 2025
8b82869
Refactor graph components to improve layout and functionality
Anchel123 May 15, 2025
00c3abc
Enhance Graph and Schema Contexts with New State Management
Anchel123 May 15, 2025
1a2e6de
Merge branch 'staging' into display-selected-graph-name
Anchel123 May 15, 2025
632d259
fix typo
Anchel123 May 15, 2025
f6494ac
Refactor Header and Selector components to conditionally render Creat…
Anchel123 May 15, 2025
4c4e36d
Update Header Component Logic in NextAuthProvider
Anchel123 May 15, 2025
92087a0
Remove unused imports from Selector component for cleaner code
Anchel123 May 15, 2025
370a0dc
Update Header component to use new popover foreground background clas…
Anchel123 May 15, 2025
63fff17
Enhance Header component with new dropdown menu items and add Discord…
Anchel123 May 15, 2025
3567936
Merge pull request #960 from FalkorDB/update-side-menu
Anchel123 May 18, 2025
3473528
Merge pull request #959 from FalkorDB/fix-typo
Anchel123 May 18, 2025
f23c3f5
Merge branch 'staging' into when-navigate-to-diffrent-page-reset-data
Anchel123 May 18, 2025
b4a1286
Merge pull request #957 from FalkorDB/display-selected-graph-name
Anchel123 May 18, 2025
7056b1b
Merge pull request #956 from FalkorDB/label-relation-toggle-indicator
Anchel123 May 18, 2025
25fe38c
Merge pull request #955 from FalkorDB/fix-query-history
Anchel123 May 18, 2025
67f6b47
Merge pull request #954 from FalkorDB/fix-tooltips
Anchel123 May 18, 2025
4aa187c
Merge branch 'staging' into when-navigate-to-diffrent-page-reset-data
Anchel123 May 18, 2025
6731a90
fix create
Anchel123 May 18, 2025
291a4e0
Merge pull request #958 from FalkorDB/when-navigate-to-diffrent-page-…
Anchel123 May 18, 2025
d56b781
Fix query syntax for creating relationships in the graph schema
Anchel123 May 18, 2025
f9b7314
mid commit
Anchel123 May 18, 2025
b86d6cc
Update error handling in FormComponent to conditionally display error…
Anchel123 May 19, 2025
2fafbc9
Refactor Combobox component and update related components to improve …
Anchel123 May 19, 2025
c7e6af4
Merge pull request #963 from FalkorDB/fix-create-edge
Anchel123 May 19, 2025
4a662e3
Merge pull request #964 from FalkorDB/leave-space-for-error-message-i…
Anchel123 May 19, 2025
3a2d54f
Merge pull request #965 from FalkorDB/update-help-menu
Anchel123 May 19, 2025
e1cc3c3
mid commit
Anchel123 May 19, 2025
2c91600
commit
Anchel123 May 19, 2025
fe2fc1f
Merge pull request #966 from FalkorDB/fix-combobox
Anchel123 May 19, 2025
d974e00
add return when fetch count doesn't return 200 ok
Anchel123 May 20, 2025
fbe7f60
Refactor TableView component to utilize useMemo for optimized data ha…
Anchel123 May 20, 2025
aabe700
Refactor Combobox and Selector components for improved user feedback …
Anchel123 May 20, 2025
1ac4087
Merge branch 'staging' into improve-ui-to-handle-multiple-labels
Anchel123 May 20, 2025
eb73a7a
Refactor PaginationList and Combobox components to enhance functional…
Anchel123 May 20, 2025
9d9d014
Merge pull request #967 from FalkorDB/improve-ui-to-handle-multiple-l…
barakb May 21, 2025
398a66e
Merge branch 'staging' into fix-select-graph
barakb May 21, 2025
f0c8387
Merge pull request #969 from FalkorDB/fix-select-graph
barakb May 21, 2025
a47d398
Merge branch 'staging' into fix-fetch-count
barakb May 21, 2025
891e971
Merge pull request #968 from FalkorDB/fix-fetch-count
barakb May 21, 2025
1201cba
add pulling on fetch count
Anchel123 May 21, 2025
e10b94d
fix data panel
Anchel123 May 21, 2025
b2a28de
Merge pull request #973 from FalkorDB/add-pulling-to-fetch-count-end-…
barakb May 21, 2025
cb3174d
fix pulling on fetch
Anchel123 May 21, 2025
2d8248b
Merge pull request #974 from FalkorDB/add-pulling-to-fetch-count-end-…
barakb May 22, 2025
4cc43b9
Merge pull request #975 from FalkorDB/fix-data-panel
barakb May 22, 2025
613682e
Enhance TableComponent to support dynamic entity names for search pla…
Anchel123 May 22, 2025
67be6d6
Merge pull request #976 from FalkorDB/fix-menage-graphs-dialog
Anchel123 May 22, 2025
77f218f
Enhance EditorComponent functionality. add clear button in the editor…
Anchel123 May 22, 2025
989034f
Enhance Header component to toggle settings page navigation based on …
Anchel123 May 22, 2025
8a0a800
Merge pull request #977 from FalkorDB/add-clear-button-to-query-editor
Anchel123 May 22, 2025
697ac4f
Merge pull request #978 from FalkorDB/make-settings-button-go-back-on…
Anchel123 May 22, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 8 additions & 5 deletions app/api/graph/[graph]/[node]/[key]/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ export async function POST(request: NextRequest, { params }: { params: Promise<{
return session
}

const { client } = session

const { client, user } = session
const { graph: graphId, node, key } = await params
const nodeId = Number(node)
const { value, type } = await request.json()
Expand All @@ -25,7 +24,9 @@ export async function POST(request: NextRequest, { params }: { params: Promise<{
? `MATCH (n) WHERE ID(n) = $nodeId SET n.${key} = $value`
: `MATCH (n)-[e]-(m) WHERE ID(e) = $nodeId SET e.${key} = $value`;

const result = await graph.query(query, { params: { nodeId, value } });
const result = user.role === "Read-Only"
? await graph.roQuery(query, { params: { nodeId, value } })
: await graph.query(query, { params: { nodeId, value } });

if (!result) throw new Error("Something went wrong")

Expand All @@ -42,7 +43,7 @@ export async function DELETE(request: NextRequest, { params }: { params: Promise
return session
}

const { client } = session
const { client, user } = session

const { graph: graphId, node, key } = await params
const nodeId = Number(node)
Expand All @@ -57,7 +58,9 @@ export async function DELETE(request: NextRequest, { params }: { params: Promise
? `MATCH (n) WHERE ID(n) = $nodeId SET n.${key} = NULL`
: `MATCH (n)-[e]-(m) WHERE ID(e) = $nodeId SET e.${key} = NULL`;

const result = await graph.query(query, { params: { nodeId } });
const result = user.role === "Read-Only"
? await graph.roQuery(query, { params: { nodeId } })
: await graph.query(query, { params: { nodeId } });

if (!result) throw new Error("Something went wrong")

Expand Down
14 changes: 8 additions & 6 deletions app/api/graph/[graph]/[node]/label/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ export async function DELETE(request: NextRequest, { params }: { params: Promise
return session
}

const { client } = session

const { client, user } = session
const { graph: graphId, node } = await params
const nodeId = Number(node)
const { label } = await request.json()
Expand All @@ -20,7 +19,9 @@ export async function DELETE(request: NextRequest, { params }: { params: Promise

const query = `MATCH (n) WHERE ID(n) = $nodeId REMOVE n:${label}`
const graph = client.selectGraph(graphId);
const result = await graph.query(query, { params: { nodeId } })
const result = user.role === "Read-Only"
? await graph.roQuery(query, { params: { nodeId } })
: await graph.query(query, { params: { nodeId } })

if (!result) throw new Error("Something went wrong")

Expand All @@ -39,8 +40,7 @@ export async function POST(request: NextRequest, { params }: { params: Promise<{
return session
}

const { client } = session

const { client, user } = session
const { graph: graphId, node } = await params
const nodeId = Number(node)
const { label } = await request.json()
Expand All @@ -50,7 +50,9 @@ export async function POST(request: NextRequest, { params }: { params: Promise<{

const query = `MATCH (n) WHERE ID(n) = $nodeId SET n:${label}`
const graph = client.selectGraph(graphId);
const result = await graph.query(query, { params: { nodeId } })
const result = user.role === "Read-Only"
? await graph.roQuery(query, { params: { nodeId } })
: await graph.query(query, { params: { nodeId } })

if (!result) throw new Error("Something went wrong")

Expand Down
27 changes: 15 additions & 12 deletions app/api/graph/[graph]/[node]/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,22 @@ export async function GET(request: NextRequest, { params }: { params: Promise<{
return session
}

const { client } = session

const { client, user } = session
const { graph: graphId, node } = await params
const nodeId = Number(node)

const graph = client.selectGraph(graphId);
try {
const graph = client.selectGraph(graphId);

// Get node's neighbors
const query = `MATCH (src)-[e]-(n)
WHERE ID(src) = $nodeId
RETURN e, n`;

// Get node's neighbors
const query = `MATCH (src)-[e]-(n)
WHERE ID(src) = $nodeId
RETURN e, n`;
const result = user.role === "Read-Only"
? await graph.roQuery(query, { params: { nodeId } })
: await graph.query(query, { params: { nodeId } })

try {
const result = await graph.query(query, { params: { nodeId } });
return NextResponse.json({ result }, { status: 200 })
} catch (err: unknown) {
console.error(err)
Expand All @@ -36,8 +38,7 @@ export async function DELETE(request: NextRequest, { params }: { params: Promise
return session
}

const { client } = session

const { client, user } = session
const { graph: graphId, node } = await params
const nodeId = Number(node)
const { type } = await request.json()
Expand All @@ -49,7 +50,9 @@ export async function DELETE(request: NextRequest, { params }: { params: Promise
const query = type
? `MATCH (n) WHERE ID(n) = $nodeId DELETE n`
: `MATCH ()-[e]-() WHERE ID(e) = $nodeId DELETE e`;
const result = await graph.query(query, { params: { nodeId } });
const result = user.role === "Read-Only"
? await graph.roQuery(query, { params: { nodeId } })
: await graph.query(query, { params: { nodeId } })

if (!result) throw new Error("Something went wrong")

Expand Down
23 changes: 14 additions & 9 deletions app/api/graph/[graph]/count/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,25 @@
return session
}

const { client } = session

const { graph: graphId } = await params
const { graph } = await params

try {
const graph = client.selectGraph(graphId)
const query = "MATCH (n) OPTIONAL MATCH (n)-[e]->() WITH count(n) as nodes, count(e) as edges RETURN nodes, edges"
const { data } = await graph.query(query)

if (!data) throw new Error("Something went wrong")

const result = data.length === 0 ? { nodes: 0, edges: 0 } : data[0]
const result = await fetch(`${request.nextUrl.origin}/api/graph/${graph}/?query=${encodeURIComponent(query)}`, {
method: "GET",
headers: {
cookie: request.headers.get('cookie') || '',
}
})
Comment on lines +17 to +22

Check failure

Code scanning / CodeQL

Server-side request forgery

The [URL](1) of this request depends on a [user-provided value](2).

Copilot Autofix

AI 2 days ago

To fix the issue, we need to validate and sanitize the graph parameter before using it in the URL. The best approach is to restrict the graph parameter to a predefined set of allowed values (an allow-list). This ensures that only expected and safe values are used in the URL. If the graph parameter does not match any of the allowed values, the request should be rejected.

Steps to implement the fix:

  1. Define an allow-list of valid graph values.
  2. Check if the graph parameter matches one of the allowed values.
  3. If the graph parameter is invalid, return an error response.
  4. Use the validated graph value in the URL.

Suggested changeset 1
app/api/graph/[graph]/count/route.ts

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/app/api/graph/[graph]/count/route.ts b/app/api/graph/[graph]/count/route.ts
--- a/app/api/graph/[graph]/count/route.ts
+++ b/app/api/graph/[graph]/count/route.ts
@@ -13,2 +13,9 @@
 
+    // Define an allow-list of valid graph names
+    const allowedGraphs = ["graph1", "graph2", "graph3"];
+
+    if (!allowedGraphs.includes(graph)) {
+        return NextResponse.json({ error: "Invalid graph parameter" }, { status: 400 });
+    }
+
     try {
EOF
@@ -13,2 +13,9 @@

// Define an allow-list of valid graph names
const allowedGraphs = ["graph1", "graph2", "graph3"];

if (!allowedGraphs.includes(graph)) {
return NextResponse.json({ error: "Invalid graph parameter" }, { status: 400 });
}

try {
Copilot is powered by AI and may make mistakes. Always verify output.
Comment on lines +17 to +22
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Mitigate potential SSRF vulnerability by validating the graph parameter

The URL of the fetch request is constructed using a user-provided value (graph parameter). While this is an internal request within the same application, it's still important to validate this parameter to prevent path traversal or other injection attacks.

    const { graph } = await params
+   
+   // Validate graph parameter to prevent path traversal or injection
+   if (!graph || /[^a-zA-Z0-9_-]/.test(graph)) {
+       return NextResponse.json({ error: "Invalid graph name" }, { status: 400 })
+   }

    try {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const result = await fetch(`${request.nextUrl.origin}/api/graph/${graph}/?query=${encodeURIComponent(query)}`, {
method: "GET",
headers: {
cookie: request.headers.get('cookie') || '',
}
})
const { graph } = await params
// Validate graph parameter to prevent path traversal or injection
if (!graph || /[^a-zA-Z0-9_-]/.test(graph)) {
return NextResponse.json({ error: "Invalid graph name" }, { status: 400 })
}
try {
const result = await fetch(
`${request.nextUrl.origin}/api/graph/${graph}/?query=${encodeURIComponent(query)}`,
{
method: "GET",
headers: {
cookie: request.headers.get('cookie') || '',
},
}
)
// …
🧰 Tools
🪛 GitHub Check: CodeQL

[failure] 17-22: Server-side request forgery
The URL of this request depends on a user-provided value.

🤖 Prompt for AI Agents
In app/api/graph/[graph]/count/route.ts around lines 17 to 22, the fetch URL
uses the user-provided graph parameter directly, which can lead to SSRF or path
traversal vulnerabilities. To fix this, validate the graph parameter against a
whitelist of allowed values or ensure it matches a strict pattern (e.g.,
alphanumeric and limited length) before using it in the URL. Reject or sanitize
any invalid input to prevent injection attacks.


if (!result.ok) throw new Error("Something went wrong")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Improve error handling with specific error details

The current error message is too generic, making debugging difficult.

- if (!result.ok) throw new Error("Something went wrong")
+ if (!result.ok) {
+   const errorText = await result.text().catch(() => "Could not read error response");
+   throw new Error(`Failed to fetch graph data: ${result.status} ${result.statusText}. ${errorText}`);
+ }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (!result.ok) throw new Error("Something went wrong")
if (!result.ok) {
const errorText = await result.text().catch(() => "Could not read error response");
throw new Error(`Failed to fetch graph data: ${result.status} ${result.statusText}. ${errorText}`);
}
🤖 Prompt for AI Agents
In app/api/graph/[graph]/count/route.ts at line 24, the error thrown uses a
generic message "Something went wrong" which lacks specific details. Modify the
error handling to include more specific information from the result object, such
as an error message or status code, to provide clearer context for debugging
when the operation fails.


const json = await result.json()

const data = typeof json.result === "number" ? json.result : { data: [json.result.data[0] || { edges: 0, nodes: 0 }] }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix data transformation logic

The current data transformation is incorrect and inconsistent. The ternary operator creates different data structures based on the type of json.result, which can lead to unexpected behavior.

- const data = typeof json.result === "number" ? json.result : { data: [json.result.data[0] || { edges: 0, nodes: 0 }] }
+ let data;
+ if (typeof json.result === "number") {
+     data = { data: [{ edges: 0, nodes: json.result }] };
+ } else if (json.result?.data?.[0]) {
+     data = { data: [json.result.data[0]] };
+ } else {
+     data = { data: [{ edges: 0, nodes: 0 }] };
+ }

This ensures a consistent data structure regardless of the input format, and includes proper validation of nested properties.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const data = typeof json.result === "number" ? json.result : { data: [json.result.data[0] || { edges: 0, nodes: 0 }] }
let data;
if (typeof json.result === "number") {
data = { data: [{ edges: 0, nodes: json.result }] };
} else if (json.result?.data?.[0]) {
data = { data: [json.result.data[0]] };
} else {
data = { data: [{ edges: 0, nodes: 0 }] };
}
🤖 Prompt for AI Agents
In app/api/graph/[graph]/count/route.ts at line 28, the data transformation uses
a ternary operator that results in inconsistent data structures depending on
whether json.result is a number or an object. To fix this, refactor the logic to
always produce a consistent data structure by validating nested properties
properly and ensuring the output format is uniform regardless of input type.


return NextResponse.json({ result }, { status: 200 })
return NextResponse.json({ result: data }, { status: 200 })
} catch (error) {
console.log(error)
return NextResponse.json({ error: (error as Error).message }, { status: 400 })
Expand Down
26 changes: 26 additions & 0 deletions app/api/graph/[graph]/duplicate/route.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { getClient } from "@/app/api/auth/[...nextauth]/options"
import { NextResponse, NextRequest } from "next/server"

// eslint-disable-next-line import/prefer-default-export
export async function PATCH(request: NextRequest, { params }: { params: Promise<{ graph: string }> }) {
const session = await getClient()

if (session instanceof NextResponse) {
return session
}

const { client } = session
const { graph: graphId } = await params
const sourceName = request.nextUrl.searchParams.get("sourceName")

try {
if (!sourceName) throw new Error("Missing parameter sourceName")

const result = await client.selectGraph(sourceName).copy(graphId)
Comment on lines +16 to +19
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Consider adding validation for target graph name

The current implementation validates the source graph name but doesn't check if the target graph already exists. This could potentially lead to overwriting an existing graph.


🏁 Script executed:

#!/bin/bash
# Check if there's any validation in the client.selectGraph().copy() method
# that prevents overwriting existing graphs

# Find any graph copy implementation in the codebase
rg -A 5 -B 5 "\.copy\(" --type ts

Length of output: 1785


Add validation for target graph name to prevent overwriting

Ensure you validate the graphId parameter and check that a graph with this name doesn’t already exist before calling .copy().

• app/api/graph/[graph]/duplicate/route.tsx (around lines 16–19):
– Throw if graphId is missing
– Query the client to see if a graph with graphId already exists and error out if so

Example diff:

     try {
-        if (!sourceName) throw new Error("Missing parameter sourceName")
-
-        const result = await client.selectGraph(sourceName).copy(graphId)
+        if (!sourceName) throw new Error("Missing parameter sourceName")
+
+        const graphId = request.nextUrl.searchParams.get("graphId")
+        if (!graphId) throw new Error("Missing parameter graphId")
+
+        // Prevent overwriting an existing graph
+        const exists = await client
+          .selectGraph(graphId)
+          .get()
+          .then(() => true)
+          .catch(err => err.message.includes("NotFound") ? false : Promise.reject(err))
+        if (exists) throw new Error(`Graph "${graphId}" already exists`)
+
+        const result = await client.selectGraph(sourceName).copy(graphId)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
try {
if (!sourceName) throw new Error("Missing parameter sourceName")
const result = await client.selectGraph(sourceName).copy(graphId)
try {
if (!sourceName) throw new Error("Missing parameter sourceName")
const graphId = request.nextUrl.searchParams.get("graphId")
if (!graphId) throw new Error("Missing parameter graphId")
// Prevent overwriting an existing graph
const exists = await client
.selectGraph(graphId)
.get()
.then(() => true)
.catch(err => err.message.includes("NotFound") ? false : Promise.reject(err))
if (exists) throw new Error(`Graph "${graphId}" already exists`)
const result = await client.selectGraph(sourceName).copy(graphId)


return NextResponse.json({ result })
} catch (error) {
console.error(error)
return NextResponse.json({ error: (error as Error).message }, { status: 400 })
}
}
1 change: 1 addition & 0 deletions app/api/graph/[graph]/query/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const INITIAL = Number(process.env.INITIAL) || 0
// eslint-disable-next-line import/prefer-default-export
export async function GET(request: NextRequest) {
const session = await getClient()

if (session instanceof NextResponse) {
return session
}
Expand Down
6 changes: 4 additions & 2 deletions app/api/graph/[graph]/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,15 @@ export async function POST(request: NextRequest, { params }: { params: Promise<{
return session
}

const { client } = session
const { client, user } = session

const { graph: graphId } = await params

try {
const graph = client.selectGraph(graphId)
const result = await graph.query("RETURN 1")
const result = user.role === "Read-Only"
? await graph.roQuery("RETURN 1")
: await graph.query("RETURN 1")

if (!result) throw new Error("Something went wrong")

Expand Down
10 changes: 5 additions & 5 deletions app/api/graph/[graph]/suggestions/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,15 @@ import { NextRequest, NextResponse } from "next/server"
// eslint-disable-next-line import/prefer-default-export
export async function GET(request: NextRequest, { params }: { params: Promise<{ graph: string }> }) {
const session = await getClient()

if (session instanceof NextResponse) {
return session
}

const { client } = session

const { client, user } = session
const { graph: graphId } = await params

const type = request.nextUrl.searchParams.get("type") as "(function)" | "(property key)" | "(label)" | "(relationship type)" | undefined


try {

const getQuery = () => {
Expand All @@ -34,7 +32,9 @@ export async function GET(request: NextRequest, { params }: { params: Promise<{

const graph = client.selectGraph(graphId)

const result = await graph.query(getQuery())
const result = user.role === "Read-Only"
? await graph.roQuery(getQuery())
: await graph.query(getQuery())

return NextResponse.json({ result }, { status: 200 })
} catch (error) {
Expand Down
Loading
Loading