# Hide all flows other than the ID in the current URL

**URL:** <https://discourse.nodered.org/t/hide-all-flows-other-than-the-id-in-the-current-url/84006>\
**Category:** Feature Requests\
**Created:** [24 December 2023 17:16 UTC](https://discourse.nodered.org/t/hide-all-flows-other-than-the-id-in-the-current-url/84006 "2023-12-24T17:16:46Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![Ahmad44452](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/ahmad44452/32/86374_2.png) [@Ahmad44452](https://discourse.nodered.org/u/Ahmad44452)\
**Post date:** [24 December 2023 17:16 UTC](https://discourse.nodered.org/t/hide-all-flows-other-than-the-id-in-the-current-url/84006/1 "2023-12-24T17:16:46Z")

</div>

Hello everyone. I have a requirement of opening only the flow whose ID is specified in the URL while opening Node-RED. After spending some time, I was able to achieve the desired results. I was wondering if I could make a pull request and make this an official feature. Since I am done developing it, I will share my code snippet as well. Following is the new `loadFlows` function along with all the changes. I have also added comments (line 20 & line 24). Let me know what do you think. Thank you.

```auto
function loadFlows(done) {
        loader.reportProgress(RED._("event.loadFlows"), 80)
        $.ajax({
            headers: {
                "Accept": "application/json",
            },
            cache: false,
            url: 'flows',
            success: function (nodes) {
                if (nodes) {
                    var currentHash = window.location.hash;
                    RED.nodes.version(nodes.rev);
                    loader.reportProgress(RED._("event.importFlows"), 90)
                    try {
                        RED.nodes.import(nodes.flows);
                        RED.nodes.dirty(false);
                        RED.view.redraw(true);
                        if (/^#(flow|node|group)\/.+$/.test(currentHash)) {
                            const hashParts = currentHash.split('/');
                            // check if "hideOtherFlows" parameter is passed
                            const hideOtherFlows = hashParts.length > 2 && (hashParts[2] === 'hideOtherFlows' || hashParts[3] === 'hideOtherFlows');
                            const showEditDialog = hashParts.length > 2 && hashParts[2] === 'edit';
                            if (hashParts[0] === '#flow') {
                                // if parameter is passed, hide all flows initially
                                // the flow having id specified in url will be made visible later
                                if (hideOtherFlows) {
                                    const workspaces = RED.nodes.getWorkspaceOrder();
                                    for (let index = 0; index < workspaces.length; index++) {
                                        RED.workspaces.hide(workspaces[index])
                                    }
                                }
                                RED.workspaces.show(hashParts[1], true);
                                if (showEditDialog) {
                                    RED.workspaces.edit()
                                }
                            } else if (hashParts[0] === '#node') {
                                const nodeToShow = RED.nodes.node(hashParts[1])
                                if (nodeToShow) {
                                    setTimeout(() => {
                                        RED.view.reveal(nodeToShow.id)
                                        window.location.hash = currentHash
                                        RED.view.select(nodeToShow.id)
                                        if (showEditDialog) {
                                            RED.editor.edit(nodeToShow)
                                        }
                                    }, 50)
                                }
                            } else if (hashParts[0] === '#group') {
                                const nodeToShow = RED.nodes.group(hashParts[1])
                                if (nodeToShow) {
                                    RED.view.reveal(nodeToShow.id)
                                    window.location.hash = currentHash
                                    RED.view.select(nodeToShow.id)
                                    if (showEditDialog) {
                                        RED.editor.editGroup(nodeToShow)
                                    }
                                }
                            }
                        }
                        if (RED.workspaces.count() > 0) {
                            const hiddenTabs = JSON.parse(RED.settings.getLocal("hiddenTabs") || "{}");
                            const workspaces = RED.nodes.getWorkspaceOrder();
                            if (RED.workspaces.active() === 0) {
                                for (let index = 0; index < workspaces.length; index++) {
                                    const ws = workspaces[index];
                                    if (!hiddenTabs[ws]) {
                                        RED.workspaces.show(ws);
                                        break;
                                    }
                                }
                            }
                            if (RED.workspaces.active() === 0) {
                                RED.workspaces.show(workspaces[0]);
                            }
                        }
                    } catch (err) {
                        console.warn(err);
                        RED.notify(
                            RED._("event.importError", { message: err.message }),
                            {
                                fixed: true,
                                type: 'error'
                            }
                        );
                    }
                }
                done();
            }
        });
    }

```

---

<div class="post-metadata">

**Author:** ![GogoVega](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/gogovega/32/71313_2.png) [@GogoVega](https://discourse.nodered.org/u/GogoVega)\
**Post date:** [24 December 2023 17:21 UTC](https://discourse.nodered.org/t/hide-all-flows-other-than-the-id-in-the-current-url/84006/2 "2023-12-24T17:21:59Z")

</div>

Hi Ahmad,  
Should be in the **Feature Request** category 😉

---

<div class="post-metadata">

**Author:** ![marcus-j-davies](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/marcus-j-davies/32/103435_2.png) [@marcus-j-davies](https://discourse.nodered.org/u/marcus-j-davies)\
**Post date:** [24 December 2023 17:35 UTC](https://discourse.nodered.org/t/hide-all-flows-other-than-the-id-in-the-current-url/84006/3 "2023-12-24T17:35:28Z")

</div>

I Moved it

And welcome to the forums @Ahmad44452

---

<div class="post-metadata">

**Author:** ![Steve-Mcl](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/steve-mcl/32/4826_2.png) [@Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)\
**Post date:** [24 December 2023 19:37 UTC](https://discourse.nodered.org/t/hide-all-flows-other-than-the-id-in-the-current-url/84006/4 "2023-12-24T19:37:47Z")

</div>

> [@Ahmad44452](#):
>
> Let me know what do you think

Hi @Ahmad44452

Can I ask why? I mean it is fairly innocuous and I don't see any reason to say no but I am not certain what the value is?

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [24 December 2023 19:57 UTC](https://discourse.nodered.org/t/hide-all-flows-other-than-the-id-in-the-current-url/84006/5 "2023-12-24T19:57:52Z")

</div>

> [@Steve-Mcl](#):
>
> I mean it is fairly innocuous

Sorry, seems to be my season for scepticism but I'm not convinced this is wise.

As far as I can see, it doesn't really securely prevent access to the other flows? Couldn't a custom node undo it for example? Only on my phone so can't really check.

If the purpose of this change is security, would need more thought?

---

<div class="post-metadata">

**Author:** ![Steve-Mcl](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/steve-mcl/32/4826_2.png) [@Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)\
**Post date:** [24 December 2023 20:07 UTC](https://discourse.nodered.org/t/hide-all-flows-other-than-the-id-in-the-current-url/84006/6 "2023-12-24T20:07:10Z")

</div>

> [@TotallyInformation](#):
>
> As far as I can see, it doesn't really securely prevent access to the other flows

I never thought it did Julian. And the reason I was asking. If it's for viewing purposes only (e.g. for training env or for quick management via hyperlinks to particular functionality) then I'm cool (i.e. it's innocuous) but if it's some kinda faux security thing, I'm not as it could give users a false sense of security.

---

<div class="post-metadata">

**Author:** ![GogoVega](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/gogovega/32/71313_2.png) [@GogoVega](https://discourse.nodered.org/u/GogoVega)\
**Post date:** [24 December 2023 20:13 UTC](https://discourse.nodered.org/t/hide-all-flows-other-than-the-id-in-the-current-url/84006/7 "2023-12-24T20:13:39Z")

</div>

If the goal is just to open a particular flow - all you need is the URL of the flow (already implemented)

If the goal is to restrict access to a flow - it is not by changing loadFlow that it will effectively change things. With this approach only one flow will be loaded, which can pose a problem during a full deployment. If we take the root of the URL we will have access to all flows.

It's not as simple as a request

---

<div class="post-metadata">

**Author:** ![Ahmad44452](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/ahmad44452/32/86374_2.png) [@Ahmad44452](https://discourse.nodered.org/u/Ahmad44452)\
**Post date:** [25 December 2023 04:51 UTC](https://discourse.nodered.org/t/hide-all-flows-other-than-the-id-in-the-current-url/84006/8 "2023-12-25T04:51:25Z")

</div>

> [@marcus-j-davies](#):
>
> And welcome to the forums @Ahmad44452

Thank you!

> [@Steve-Mcl](#):
>
> Can I ask why?

@Steve-Mcl we are trying to embed Node-RED in our web app where users can build some flow using Node-RED, which then will be used to perform certain execution. These will be trusted users and will be authenticated beforehand but we were looking to make some changes in order to give a better UI experience.

The user will basically be creating flow with the click of a button on our web-page (which will be done by hitting Node-RED admin API) then that newly created flow will be opened in an iframe where that user can create any kind of flow. To give a better UI, we were looking for quite a few changes, for example, disabling the `add flow` button within Node-RED, hiding all the irrelevant tabs (the current feature request) etc.

As giving access to the user only to the current flow will require a lot more thought and work, that is why we decided to go this route for now and make it UI friendly only. That is why I made this general feature request, I think everyone could benefit from. It can be used to hide all irrelevant tabs, ONLY on startup. I am open to suggestions, if there is a better way to do this or if there is a way we can give access to user only to the current flow.

While I am on it, I want to ask another question. Is it possible to have users who can make changes to the flows but not to the settings? Like to have separate super admins that have the complete access?

---

<div class="post-metadata">

**Author:** ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)\
**Post date:** [25 December 2023 09:57 UTC](https://discourse.nodered.org/t/hide-all-flows-other-than-the-id-in-the-current-url/84006/9 "2023-12-25T09:57:56Z")

</div>

> [@Ahmad44452](#):
>
> Is it possible to have users who can make changes to the flows but not to the settings?

Do you mean settings.js? If so then make it only writable by root, so that it is necessary to use sudo to access it.

---

<div class="post-metadata">

**Author:** ![Ahmad44452](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/ahmad44452/32/86374_2.png) [@Ahmad44452](https://discourse.nodered.org/u/Ahmad44452)\
**Post date:** [25 December 2023 10:10 UTC](https://discourse.nodered.org/t/hide-all-flows-other-than-the-id-in-the-current-url/84006/10 "2023-12-25T10:10:01Z")

</div>

> [@Colin](#):
>
> Do you mean settings.js? If so then make it only writable by root, so that it is necessary to use sudo to access it.

Not just settings.js but also things like creating and deleting flow, managing palette etc. Like if I want one user-base to have only read access, one user-base to have the access to change the flows only (they can change the nodes as they want in a flow but cannot add or delete the flow itself) and one user-base to have full control over everything.

---

<div class="post-metadata">

**Author:** ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)\
**Post date:** [25 December 2023 10:22 UTC](https://discourse.nodered.org/t/hide-all-flows-other-than-the-id-in-the-current-url/84006/11 "2023-12-25T10:22:02Z")

</div>

> [@Ahmad44452](#):
>
> also things like creating and deleting flow, managing palette etc.

No, I believe that is currently not possible.

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [25 December 2023 13:17 UTC](https://discourse.nodered.org/t/hide-all-flows-other-than-the-id-in-the-current-url/84006/12 "2023-12-25T13:17:39Z")

</div>

Turn off the palette manager and control node installs outside node red.

Preventing crate or delete of flow files will need fine grained ACL controls that let need red update the file but not crafted or delete files in the folder.

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/1X/d073cd938eafa2e558d7c2cd59003b3ef4963033.png) [@system](https://discourse.nodered.org/u/system)\
**Post date:** [23 February 2024 13:18 UTC](https://discourse.nodered.org/t/hide-all-flows-other-than-the-id-in-the-current-url/84006/13 "2024-02-23T13:18:25Z")

</div>

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.
