# Unexpected behavior with credentials

**URL:** <https://discourse.nodered.org/t/unexpected-behavior-with-credentials/54150>\
**Category:** Developing Nodes\
**Tags:** security\
**Created:** [23 November 2021 09:27 UTC](https://discourse.nodered.org/t/unexpected-behavior-with-credentials/54150 "2021-11-23T09:27:03Z")\
**Posts on this page:** 17\
**Page:** 1

<div class="post-metadata">

**Author:** ![Dunken](https://avatars.discourse-cdn.com/v4/letter/d/45deac/32.png) [@Dunken](https://discourse.nodered.org/u/Dunken)\
**Post date:** [23 November 2021 09:27 UTC](https://discourse.nodered.org/t/unexpected-behavior-with-credentials/54150/1 "2021-11-23T09:27:04Z")

</div>

If I add a click-handler in `oneditprepare` and update my credentials in a callback like:

```auto
$("#node-config-input-newMachineUser").click(function () {                
                //do stuff
                $.ajax({
                    type: 'post',
                    url: url, 
                    data: params, 
                    dataType: 'json',            
                    success: function(res) {
                        $('#node-config-input-machineUserId').val(res.id);
                        $('#node-config-input-clientId').val(res.oauth2ClientId);            
                        $('#node-config-input-clientSecret').val("dummySecret");                        
                    }
                });
            })

```

the credentials are gone...

However, if I a register my click-handler directly on the button it works... do I miss something?

```auto
    <div class="form-row">
        <button type="button" id="node-config-input-newMachineUser" onclick="newMachineUser()" class="red-ui-button">Create New Machine User</button> 
    </div>

```

```auto
<script type="text/javascript">
    function newMachineUser() {
        // do stuff
        $.ajax({
            type: 'post',
            url: url, 
            data: params, 
            dataType: 'json',            
            success: function(res) {
                $('#node-config-input-machineUserId').val(res.id);
                $('#node-config-input-clientId').val(res.oauth2ClientId);            
                $('#node-config-input-clientSecret').val("dummySecret")
            }
        });
    }
</script>

```

---

<div class="post-metadata">

**Author:** ![knolleary](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/knolleary/32/3_2.png) [@knolleary](https://discourse.nodered.org/u/knolleary)\
**Post date:** [23 November 2021 10:27 UTC](https://discourse.nodered.org/t/unexpected-behavior-with-credentials/54150/2 "2021-11-23T10:27:00Z")

</div>

`oneditsave` is called when the dialog is being closed. Adding a click handler at that point in time doesn't make any sense - it will never be called because you can't click the button in a dialog that has closed.

I suspect you mean to add the click handler in the `oneditprepare` function that is called when the dialog is being created.

---

<div class="post-metadata">

**Author:** ![Dunken](https://avatars.discourse-cdn.com/v4/letter/d/45deac/32.png) [@Dunken](https://discourse.nodered.org/u/Dunken)\
**Post date:** [23 November 2021 20:07 UTC](https://discourse.nodered.org/t/unexpected-behavior-with-credentials/54150/5 "2021-11-23T20:07:51Z")

</div>

Oops, that was simply stated wrong on my side. Of course I added the handler in `oneditprepare` . I just updated the post.

Still, the problem remains.

---

<div class="post-metadata">

**Author:** ![Dunken](https://avatars.discourse-cdn.com/v4/letter/d/45deac/32.png) [@Dunken](https://discourse.nodered.org/u/Dunken)\
**Post date:** [23 November 2021 21:53 UTC](https://discourse.nodered.org/t/unexpected-behavior-with-credentials/54150/6 "2021-11-23T21:53:08Z")

</div>

I'm not sure it this information matters but this is a config-node.

---

<div class="post-metadata">

**Author:** ![knolleary](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/knolleary/32/3_2.png) [@knolleary](https://discourse.nodered.org/u/knolleary)\
**Post date:** [23 November 2021 21:59 UTC](https://discourse.nodered.org/t/unexpected-behavior-with-credentials/54150/7 "2021-11-23T21:59:59Z")

</div>

@Dunken please don't delete and repost replies - it triggers duplicate notifications which isn't okay.

We'll need more information to understand what's happening here. Can you share you node's HTML so we can see how you are defining the node properties and credentials?

What have you don't to try to debug this yourself? Have you confirmed the click handler is being called? Have you verified the inputs values are being updated by the code?

---

<div class="post-metadata">

**Author:** ![Dunken](https://avatars.discourse-cdn.com/v4/letter/d/45deac/32.png) [@Dunken](https://discourse.nodered.org/u/Dunken)\
**Post date:** [24 November 2021 07:49 UTC](https://discourse.nodered.org/t/unexpected-behavior-with-credentials/54150/8 "2021-11-24T07:49:18Z")

</div>

I'm sorry for the deletes and I also mixed up a few things... Let me start from scratch 🙂

I have a config-node where I want to create a machine-user in the background. First I thought I would introduce a button inside the editor dialog. For this I attached the click-handler in `oneditprepare` (I also tried in html itself but result is the same as expected). This is working as expected which means that the ajax-callback stores the credentials in the three cred-fields.

Here's the code for this:

```auto
oneditprepare: function() {
            var node = this;

            $("#node-config-input-newMachineUser").click(function () {                
                //do stuff
                $.ajax({
                    type: 'post',
                    url: url, 
                    data: params, 
                    dataType: 'json',            
                    success: function(res) {
                        $('#node-config-input-machineUserId').val(res.id);
                        $('#node-config-input-clientId').val(res.oauth2ClientId);            
                        $('#node-config-input-clientSecret').val("dummySecret");                        
                    }
                });
            })        
        },

```

While this is great it has one drawback: if the user clicks on cancel button after the create button the user is already created (I first wanted to delete user in `oneditcancel` but this didn't work either as `this` doesn't point to the context in `oneditcancel`...).

Anyway instead of using an extra button at all I turned to simply do stuff when a user click on "Add". I moved the code from the click-handler to `oneditsave`:

```auto
        oneditsave: function() {
            // do stuff
            $.ajax({
                type: 'post',
                url: url, 
                data: params, 
                dataType: 'json',            
                success: function(res) {
                    $('#node-config-input-machineUserId').val(res.id);
                    $('#node-config-input-clientId').val(res.oauth2ClientId);            
                    $('#node-config-input-clientSecret').val("dummySecret");                        
                }   
            });
        },

```

While the success-callback gets called as excpected (and the three fields set), `this.credentials` is empty afterwards. This means when I open up again the editor the three fields set in the callback are empty.

---

<div class="post-metadata">

**Author:** ![knolleary](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/knolleary/32/3_2.png) [@knolleary](https://discourse.nodered.org/u/knolleary)\
**Post date:** [24 November 2021 08:38 UTC](https://discourse.nodered.org/t/unexpected-behavior-with-credentials/54150/9 "2021-11-24T08:38:26Z")

</div>

You cannot do asynchronous work like that in `oneditsave`. By the time it completes, the dialog will have been closed and none of the inputs will exist.

---

<div class="post-metadata">

**Author:** ![Dunken](https://avatars.discourse-cdn.com/v4/letter/d/45deac/32.png) [@Dunken](https://discourse.nodered.org/u/Dunken)\
**Post date:** [24 November 2021 08:53 UTC](https://discourse.nodered.org/t/unexpected-behavior-with-credentials/54150/10 "2021-11-24T08:53:53Z")

</div>

OK, that makes sense. Then I would fall back to my first solution (add button and use click handler). However, what's best practice how to do handle a `Cancel`? I definitively need to clean-up in this case. As I mentioned `this` is almost empty in `oneditcancel` (it actually only contains the `id` of the node itself) but even if it would be populated I guess the same restriction applies and I can't do any asynchronous calls in `oneditcancel`...

Surely I could provide a clean-up button but I don't like to leave this to up to the user...

---

<div class="post-metadata">

**Author:** ![knolleary](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/knolleary/32/3_2.png) [@knolleary](https://discourse.nodered.org/u/knolleary)\
**Post date:** [24 November 2021 08:57 UTC](https://discourse.nodered.org/t/unexpected-behavior-with-credentials/54150/11 "2021-11-24T08:57:27Z")

</div>

You can make async calls in oneditsave and oneditcancel - you just cannot interact with the edit dialog when they complete.

So it would seem for the cancel case, you can fire off the request to remove the credentials without needing to do anything when it completes.

---

<div class="post-metadata">

**Author:** ![Dunken](https://avatars.discourse-cdn.com/v4/letter/d/45deac/32.png) [@Dunken](https://discourse.nodered.org/u/Dunken)\
**Post date:** [24 November 2021 09:13 UTC](https://discourse.nodered.org/t/unexpected-behavior-with-credentials/54150/12 "2021-11-24T09:13:59Z")

</div>

OK, that also make sense 🙂 Then I'm back to the problem with `this`... for some reason I don't have access to `this.credentials` or anything else but the `id`...

![image (4)](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/8/c/8cfb057bec1e1f01a625fbe0620ddfdb460fb9b5.png)

FYI: `console.log(RED.nodes.node(node.id));` returns `null`

Could it be because it's a config-node?

---

<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 November 2021 15:10 UTC](https://discourse.nodered.org/t/unexpected-behavior-with-credentials/54150/13 "2021-11-24T15:10:21Z")

</div>

BTW, those calls don't HAVE to be async, you should be able to force them to wait. Obviously that causes a pause to the user.

> <https://stackoverflow.com/questions/133310/how-can-i-get-jquery-to-perform-a-synchronous-rather-than-asynchronous-ajax-re/133327#133327>

---

<div class="post-metadata">

**Author:** ![knolleary](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/knolleary/32/3_2.png) [@knolleary](https://discourse.nodered.org/u/knolleary)\
**Post date:** [24 November 2021 15:11 UTC](https://discourse.nodered.org/t/unexpected-behavior-with-credentials/54150/14 "2021-11-24T15:11:59Z")

</div>

> [@TotallyInformation](#):
>
> Obviously that causes a pause to the user.

And triggers a number of deprecation warnings in most modern browsers.

Just because you can, doesn't mean you should. 😉

---

<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 November 2021 15:13 UTC](https://discourse.nodered.org/t/unexpected-behavior-with-credentials/54150/15 "2021-11-24T15:13:50Z")

</div>

Sheesh, some warnings are meant to be ignored 🤣  
Sometimes sync IS better than async 😉

---

<div class="post-metadata">

**Author:** ![Dunken](https://avatars.discourse-cdn.com/v4/letter/d/45deac/32.png) [@Dunken](https://discourse.nodered.org/u/Dunken)\
**Post date:** [24 November 2021 16:38 UTC](https://discourse.nodered.org/t/unexpected-behavior-with-credentials/54150/16 "2021-11-24T16:38:26Z")

</div>

> Just because you can, doesn't mean you should. 😉

I would stick with this advice. 🙂

Any idea about my `oneditcancel` issue? I guess I could also store everything I need in a global (e.g. window) context... seems like the last resort to me though...

---

<div class="post-metadata">

**Author:** ![knolleary](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/knolleary/32/3_2.png) [@knolleary](https://discourse.nodered.org/u/knolleary)\
**Post date:** [24 November 2021 16:53 UTC](https://discourse.nodered.org/t/unexpected-behavior-with-credentials/54150/17 "2021-11-24T16:53:24Z")

</div>

As you're talking about config nodes, there are two possible scenarios here.

1. you have clicked 'add new config node'
2. you are editing an existing config node

If you cancel adding a new config node, then there is no node available to cancel - in that scenario the current code does call it with `this` set to an object with just the id of the node that would have been added.

If you cancel the edit of an existing node, `this` will be set to the full node object.

I can vaguely remember why it was done like this - the rationale being you are cancelling creating the node so why do you need access to any of the properties you are throwing away? In the cases were we interact with remote APIs to generate resources for the node, we use the node's id as the key, so that's all we needed to undo whatever was done.

Having said that, I can't see a strong reason _not_ to pass in the full node object for that scenario. Something we can look at for the imminent 2.1.4 release.

---

<div class="post-metadata">

**Author:** ![Dunken](https://avatars.discourse-cdn.com/v4/letter/d/45deac/32.png) [@Dunken](https://discourse.nodered.org/u/Dunken)\
**Post date:** [24 November 2021 19:26 UTC](https://discourse.nodered.org/t/unexpected-behavior-with-credentials/54150/18 "2021-11-24T19:26:53Z")

</div>

> 1. you have clicked 'add new config node'

That's my scenario.

> In the cases were we interact with remote APIs to generate resources for the node, we use the node's id as the key, so that's all we needed to undo whatever was done.

So you're saying instead of keeping my own id's I should always use the node-id as _the_ identifier of resources created in the backend?

> Something we can look at for the imminent 2.1.4 release.

Highly appreciated. Too late for me for the moment. Any strong reason not to store stuff in `window`?

---

<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 January 2022 19:27 UTC](https://discourse.nodered.org/t/unexpected-behavior-with-credentials/54150/19 "2022-01-23T19:27:30Z")

</div>

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