# oAuth2 server create issue

**URL:** <https://discourse.nodered.org/t/oauth2-server-create-issue/38638>\
**Category:** General\
**Created:** [6 January 2021 08:55 UTC](https://discourse.nodered.org/t/oauth2-server-create-issue/38638 "2021-01-06T08:55:44Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![msupra](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/msupra/32/34760_2.png) [@msupra](https://discourse.nodered.org/u/msupra)\
**Post date:** [6 January 2021 08:55 UTC](https://discourse.nodered.org/t/oauth2-server-create-issue/38638/1 "2021-01-06T08:55:45Z")

</div>

Hi  
I am trying to implement an oAuth2 server within node-red. One of the requirements is a model to be used which is declared as follows:

```auto
const OAuth2Server=global.get('OAuth2Server')
Request = OAuth2Server.Request,
Response = OAuth2Server.Response

const oauth = new OAuth2Server({
  model: global.get('model'),
  accessTokenLifetime: 60 * 60,
  allowBearerTokensInQueryString: true
});

```

Both OAuth2Server and model are defined in settings.js as:

```auto
functionGlobalContext: {
        os:require('os'),
        OAuth2Server:require('oauth2-server'),
        model:require('./model.js'),
    } // enables global context
};

```

This works fine, but it limits me to have an external .js file to maintain.  
I would like to have model.js as a function or config element or whatever might be suggested by the community, to enable me to edit the model from within node-red. I do not want to ship an additional .js file during deployment. I would also like to be able to create an oAuth2 server node for community distribution.

I would really appreciate some guidance. Below an excerpt from the model.js file:

```auto
/**
 * Configuration.
 */

var config = {
	clients: [{
		id: 'application',	// TODO: Needed by refresh_token grant, because there is a bug at line 103 in https://github.com/oauthjs/node-oauth2-server/blob/v3.0.1/lib/grant-types/refresh-token-grant-type.js (used client.id instead of client.clientId)
		clientId: 'application',
		clientSecret: 'secret',
		grants: [
			'password',
			'refresh_token'
		],
		redirectUris: []
	}],
	confidentialClients: [{
		clientId: 'confidentialApplication',
		clientSecret: 'topSecret',
		grants: [
			'password',
			'client_credentials'
		],
		redirectUris: []
	}],
	tokens: [],
	users: [{
		username: 'pedroetb',
		password: 'password'
	}]
};

/*
 * Methods used by all grant types.
 */

var getAccessToken = function(token) {

	var tokens = config.tokens.filter(function(savedToken) {

		return savedToken.accessToken === token;
	});

	return tokens[0];
};

var getClient = function(clientId, clientSecret) {

	var clients = config.clients.filter(function(client) {

		return client.clientId === clientId && client.clientSecret === clientSecret;
	});

	var confidentialClients = config.confidentialClients.filter(function(client) {

		return client.clientId === clientId && client.clientSecret === clientSecret;
	});

	return clients[0] || confidentialClients[0];
};
module.exports = {
	getAccessToken: getAccessToken,
	getClient: getClient,
	saveToken: saveToken,
	getUser: getUser,
	getUserFromClient: getUserFromClient,
	getRefreshToken: getRefreshToken,
	revokeToken: revokeToken
};

```

Regards  
Morne

---

<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:** [6 January 2021 09:12 UTC](https://discourse.nodered.org/t/oauth2-server-create-issue/38638/2 "2021-01-06T09:12:26Z")

</div>

> [@msupra](#):
>
> I would also like to be able to create an oAuth2 server node for community distribution.

There are already oAuth2 contrib nodes available [in the flow library](https://flows.nodered.org/search?term=oAuth2).

Do these not work for you?

Perhaps you could contribute to one of them to get it up to a good level (if need be of course)?

* * *

> [@msupra](#):
>
> This works fine, but it limits me to have an external .js file to maintain.  
> I would like to have model.js as a function or config element or whatever might be suggested by the community, to enable me to edit the model from within node-red.

you can simply copy the code from model.js to a function node & store it in global context. (change the `module.exports = {` to something like `var myModel = {` then store `myModel` in global context). you would need to trigger the function node once on start up (e.g. an inject node set to fire on start up)

---

<div class="post-metadata">

**Author:** ![msupra](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/msupra/32/34760_2.png) [@msupra](https://discourse.nodered.org/u/msupra)\
**Post date:** [6 January 2021 09:35 UTC](https://discourse.nodered.org/t/oauth2-server-create-issue/38638/3 "2021-01-06T09:35:00Z")

</div>

Hi @Steve-Mcl, thanks for the reply.  
If I am wrong, please forgive, but it looks like the oAuth2 contrib nodes are for clients and not server side.

I have previously tried something similar, but not as you suggested with the module.exports part, which kept on failing. It is still failing at the same point, but it looks like I am going in the right direction.

I will update this issue with results.

Regards  
Morne

---

<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:** [6 January 2021 09:37 UTC](https://discourse.nodered.org/t/oauth2-server-create-issue/38638/4 "2021-01-06T09:37:57Z")

</div>

> [@msupra](#):
>
> If I am wrong, please forgive, but it looks like the oAuth2 contrib nodes are for clients and not server side.

My apologies, I think you are right.

Hopefully the other info is of use.

If you do go on to create a contrib node, [this](https://nodered.org/docs/creating-nodes/) should get you started.

---

<div class="post-metadata">

**Author:** ![msupra](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/msupra/32/34760_2.png) [@msupra](https://discourse.nodered.org/u/msupra)\
**Post date:** [6 January 2021 09:40 UTC](https://discourse.nodered.org/t/oauth2-server-create-issue/38638/5 "2021-01-06T09:40:14Z")

</div>

Hi @Steve-Mcl, no worries. Yeah, I am sure that your info will help. If I can get this to work, I will definitely contribute by creating a server node.

Regards  
Morne

---

<div class="post-metadata">

**Author:** ![msupra](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/msupra/32/34760_2.png) [@msupra](https://discourse.nodered.org/u/msupra)\
**Post date:** [6 January 2021 13:10 UTC](https://discourse.nodered.org/t/oauth2-server-create-issue/38638/6 "2021-01-06T13:10:05Z")

</div>

Hi  
Ok, here is a status update and observations of the solution that is not working, but not due to the advice given by the community:

1. I have a model.js acquired via settings.js require that works as expected

```auto
const oauth = new OAuth2Server({
  model: global.get('model'),
  accessTokenLifetime: 60 * 60,
  allowBearerTokensInQueryString: true
});

```

1. I also have an exact copy of model.js in a node-red function that I inject via inject node when flow restarts and it is acquired via:

```auto
const oauth = new OAuth2Server({
  model: global.get('myModel'),
  accessTokenLifetime: 60 * 60,
  allowBearerTokensInQueryString: true
});

```

1. When I test with model acquired via point 1, I get the results as expected.
2. When I test with the model acquired via point 2, the test fails with:

```auto
Server error: `grants` must be an array

```

I tested with multiple tests and grants is an array:

```auto
{
  clientId: 'confidentialApplication',
  clientSecret: 'topSecret',
  grants: ['password', 'client_credentials'],
  redirectUris: []
}

```

1. The oauth2-server nodejs module has a handler that tests if grants is an array with:

```auto
if (!(client.grants instanceof Array)) {
        console.log("handler grants: "+client.grants)
        throw new ServerError('Server error: `grants` must be an array');
      }

```

and the test fails, even though the way I create the client object is exactly the same in point 1 and point 2.  
6. If I though change the test to:

```auto
if (!(Array.isArray(client.grants))) {
        throw new ServerError('Server error: `grants` must be an array');
      }

```

the test is successful and I get the results I expect.

I now have the question: What is the difference between the instanceof and Array.isArray test? Is there anything I can do in node-red to ensure that the instanceof test will pass?

Regards  
Morne

---

<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:** [7 March 2021 13:10 UTC](https://discourse.nodered.org/t/oauth2-server-create-issue/38638/7 "2021-03-07T13:10:19Z")

</div>

Closed on 7 March 2021 13:10 UTC

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