Repository: node-red/node-red (js)

Issue:
Group JSON Environment Variables can't be read
### Current Behavior

When trying to retrieve data stored as a JSON object in a group environment variable, the "ReferenceError: clone is not defined" error is thrown in the debug window. However, when trying to retrieve the same JSON object from a flow environment variable, it is returned as expected.

![Test Screenshot](https://github.com/node-red/node-red/assets/28307446/a74941ad-427a-41da-9dda-0c4cf3d63d2c)

![Group Variable](https://github.com/node-red/node-red/assets/28307446/2092da73-1d84-49b1-ab94-74a56b05044d)

![Flow Variable](https://github.com/node-red/node-red/assets/28307446/67b8954c-2862-4024-807c-46b2445235ee)

This is being observed in multiple deployments using v3.1.9, and I believe the same thing is happening for the J: expression variable type.

### Expected Behavior

Since data can be stored in the JSON format, it should be able to be read as such.

### Steps To Reproduce

Create two JSON environment variables - one at a group level and one at a flow level. Try referencing those variables in a flow. Example attached.

### Example flow
```
[
    {
        "id": "637ca52003cd8ddf",
        "type": "tab",
        "label": "Group Variables Issue",
        "disabled": false,
        "info": "",
        "env": [
            {
                "name": "flowFields",
                "value": "{\"test\":true}",
                "type": "json"
            }
        ]
    },
    {
        "id": "c2945ba4f9673b05",
        "type": "group",
        "z": "637ca52003cd8ddf",
        "name": "",
        "style": {
            "label": true
        },
        "nodes": [
            "177ad60a4d4db219",
            "d71bec5b3195430e",
            "e8d6b24399ad8e96",
            "6c8f40c5dc7fe1ed"
        ],
        "env": [
            {
                "name": "groupFields",
                "value": "{\"test\":true}",
                "type": "json"
            }
        ],
        "x": 814,
        "y": 239,
        "w": 512,
        "h": 122
    },
    {
        "id": "177ad60a4d4db219",
        "type": "inject",
        "z": "637ca52003cd8ddf",
        "g": "c2945ba4f9673b05",
        "name": "Group JSON Variable",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "groupFields",
        "payloadType": "env",
        "x": 960,
        "y": 280,
        "wires": [
            [
                "d71bec5b3195430e"
            ]
        ]
    },
    {
        "id": "d71bec5b3195430e",
        "type": "debug",
        "z": "637ca52003cd8ddf",
        "g": "c2945ba4f9673b05",
        "name": "group test output",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 1190,
        "y": 280,
        "wires": []
    },
    {
        "id": "e8d6b24399ad8e96",
        "type": "inject",
        "z": "637ca52003cd8ddf",
        "g": "c2945ba4f9673b05",
        "name": "Flow JSON Variable",
        "props": [
            {
                "p": "payload"
            },
            {
                "p": "topic",
                "vt": "str"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "flowFields",
        "payloadType": "env",
        "x": 950,
        "y": 320,
        "wires": [
            [
                "6c8f40c5dc7fe1ed"
            ]
        ]
    },
    {
        "id": "6c8f40c5dc7fe1ed",
        "type": "debug",
        "z": "637ca52003cd8ddf",
        "g": "c2945ba4f9673b05",
        "name": "flow test output",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "payload",
        "targetType": "msg",
        "statusVal": "",
        "statusType": "auto",
        "x": 1180,
        "y": 320,
        "wires": []
    }
]
```

### Environment

- Docker: Using the official latest nodered/node-red docker build from hub.docker.com
- Node-RED version: 3.1.9
- Node.js version: Whichever version is included in Docker image
- npm version: Whichever version is include in Docker image
- Platform/OS: Mac OS Sonoma 14.5
- Browser: Safari 17.5


Pull request:
Fix clone of group env var properties
Closes #4751



Patch:
diff --git a/packages/node_modules/@node-red/runtime/lib/flows/Group.js b/packages/node_modules/@node-red/runtime/lib/flows/Group.js
index 90d93cf45..589cdf115 100644
--- a/packages/node_modules/@node-red/runtime/lib/flows/Group.js
+++ b/packages/node_modules/@node-red/runtime/lib/flows/Group.js
@@ -1,5 +1,6 @@
 const flowUtil = require("./util");
 const credentials = require("../nodes/credentials");
+const clone = require("clone");
 
 /**
  * This class represents a group within the runtime.


Test patch:
diff --git a/test/unit/@node-red/runtime/lib/flows/Group_spec.js b/test/unit/@node-red/runtime/lib/flows/Group_spec.js
index b547b1c77..1b22b962d 100644
--- a/test/unit/@node-red/runtime/lib/flows/Group_spec.js
+++ b/test/unit/@node-red/runtime/lib/flows/Group_spec.js
@@ -16,6 +16,31 @@ describe('Group', function () {
             group.getSetting("NR_GROUP_NAME").should.equal("g1")
             group.getSetting("NR_GROUP_ID").should.equal("group1")
         })
+        it("returns cloned env var property", async function () {
+            const group = new Group({
+                getSetting: v => v+v
+            }, {
+                name: "g1",
+                id: "group1",
+                env: [
+                    {
+                        name: 'jsonEnvVar',
+                        type: 'json',
+                        value: '{"a":1}'
+                    }
+                ]
+            })
+            await group.start()
+            const result = group.getSetting('jsonEnvVar')
+            result.should.have.property('a', 1)
+            result.a = 2
+            result.b = 'hello'
+
+            const result2 = group.getSetting('jsonEnvVar')
+            result2.should.have.property('a', 1)
+            result2.should.not.have.property('b')
+
+        })
         it("delegates to parent if not found", async function () {
             const group = new Group({
                 getSetting: v => v+v