From d0290d03472f61d0134b5c02a22838a950e02257 Mon Sep 17 00:00:00 2001 From: Polle Pas Date: Tue, 23 Jul 2024 12:48:11 +0200 Subject: [PATCH] #914 Fix changing subject in new form could cause parent change in existing resources --- browser/CHANGELOG.md | 1 + .../src/components/forms/NewForm/useNewForm.ts | 5 +++++ lib/src/commit.rs | 17 +++++++++++++++++ 3 files changed, 23 insertions(+) diff --git a/browser/CHANGELOG.md b/browser/CHANGELOG.md index b090de4bd..d8f99656a 100644 --- a/browser/CHANGELOG.md +++ b/browser/CHANGELOG.md @@ -20,6 +20,7 @@ This changelog covers all five packages, as they are (for now) updated as a whol - Moved the resource context menu to the top of the page. - [#861](https://github.com/atomicdata-dev/atomic-server/issues/861) Fix long usernames overflowing on the share page. - [#906](https://github.com/atomicdata-dev/atomic-server/issues/906) Reset changes after clicking the cancel button in a form or navigating away. +- [#914](https://github.com/atomicdata-dev/atomic-server/issues/914) Fix an issue where changing the subject in a new resource form could update the parent of existing resources if their subject matched the new subject. ### @tomic/lib diff --git a/browser/data-browser/src/components/forms/NewForm/useNewForm.ts b/browser/data-browser/src/components/forms/NewForm/useNewForm.ts index 112d4ad74..7591f4434 100644 --- a/browser/data-browser/src/components/forms/NewForm/useNewForm.ts +++ b/browser/data-browser/src/components/forms/NewForm/useNewForm.ts @@ -41,6 +41,11 @@ export const useNewForm = (args: UseNewForm) => { // When the resource is created or updated, make sure that the parent and class are present useEffect(() => { (async () => { + if (!resource.new) { + // The resource we are trying to create already exists, don't update any values. + return; + } + if (parentVal !== parent) { await resource.set(core.properties.parent, parent); } diff --git a/lib/src/commit.rs b/lib/src/commit.rs index 15fff27c9..30cc04cf9 100644 --- a/lib/src/commit.rs +++ b/lib/src/commit.rs @@ -128,6 +128,9 @@ impl Commit { if opts.validate_timestamp { check_timestamp(self.created_at)?; } + + self.check_for_circular_parents()?; + let commit_resource: Resource = self.into_resource(store)?; let mut is_new = false; // Create a new resource if it doens't exist yet @@ -263,6 +266,20 @@ impl Commit { Ok(commit_response) } + fn check_for_circular_parents(&self) -> AtomicResult<()> { + // Check if the set hashset has a parent property and if it matches with this subject. + if let Some(set) = self.set.clone() { + if let Some(parent) = set.get(urls::PARENT) { + if parent.to_string() == self.subject { + return Err("Circular parent reference".into()); + } + } + } + + // TODO: Check for circular parents by going up the parent tree. + Ok(()) + } + /// Updates the values in the Resource according to the `set`, `remove`, `push`, and `destroy` attributes in the Commit. /// Optionally also updates the index in the Store. /// The Old Resource is only needed when `update_index` is true, and is used for checking